Gaudi Framework, version v21r9

Home   Generated: 3 May 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 343 of file GaudiSequencer.cpp.

00343                                                    {
00344   if ( isInitialized() ) decodeNames().ignore();
00345 }

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     //== Is it an Algorithm ?  Strange test...
00290     if ( result.isSuccess() ) {
00291       // TODO: (MCl) it is possible to avoid the dynamic_cast in most of the
00292       //             cases by keeping the result of createSubAlgorithm.
00293       Algorithm*  myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
00294       if (myAlg!=0) {
00295         // Note: The reference counting is kept by the system of sub-algorithms
00296         m_entries.push_back( AlgorithmEntry( myAlg ) );
00297         debug () << "Added algorithm " << theName << endmsg;
00298       } else {
00299         warning() << theName << " is not an Algorithm - failed dynamic_cast"
00300                   << endmsg;
00301         final = StatusCode::FAILURE;
00302       }
00303     } else {
00304       warning() << "Unable to find or create " << theName << endmsg;
00305       final = result;
00306     }
00307 
00308   }
00309   release(appMgr).ignore();
00310   release(jos).ignore();
00311 
00312   //== Print the list of algorithms
00313   MsgStream& msg = info();
00314   if ( m_modeOR ) msg << "OR ";
00315   msg << "Member list: ";
00316   std::vector<AlgorithmEntry>::iterator itE;
00317   for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
00318     Algorithm* myAlg = (*itE).algorithm();
00319     std::string myAlgType = System::typeinfoName( typeid( *myAlg) ) ;
00320     if ( myAlg->name() == myAlgType ) {
00321       msg << myAlg->name();
00322     } else {
00323       msg << myAlgType << "/" << myAlg->name();
00324     }
00325     if ( itE+1 != m_entries.end() ) msg << ", ";
00326   }
00327   if ( "" != context() ) msg << ", with context '" << context() << "'";
00328   if ( "" != rootInTES() ) msg << ", with rootInTES '" << rootInTES() << "'";
00329   if ( 0.0 != globalTimeOffset() ) msg << ", with globalTimeOffset " << globalTimeOffset();
00330   msg << endmsg;
00331 
00332   return final;
00333 
00334 }

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 Mon May 3 12:24:33 2010 for Gaudi Framework, version v21r9 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004