Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

GaudiSequencer Class Reference

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

#include <GaudiSequencer.h>

Inheritance diagram for GaudiSequencer:

Inheritance graph
[legend]
Collaboration diagram for GaudiSequencer:

Collaboration graph
[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 ( void   )  [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 333 of file GaudiSequencer.cpp.

00333                                                    {
00334   if ( isInitialized() ) decodeNames().ignore();
00335 }

StatusCode GaudiSequencer::decodeNames (  )  [protected]

Decode a vector of string.

Definition at line 186 of file GaudiSequencer.cpp.

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

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.

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 Wed Mar 17 18:17:27 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004