Gaudi Framework, version v20r2

Generated: 18 Jul 2008

GaudiSequencer Class Reference

#include <GaudiSequencer.h>

Inheritance diagram for GaudiSequencer:

Inheritance graph
[legend]
Collaboration diagram for GaudiSequencer:

Collaboration graph
[legend]
List of all members.

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.

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


Constructor & Destructor Documentation

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

Standard constructor.

Definition at line 20 of file GaudiSequencer.cpp.

References Algorithm::declareProperty(), Property::declareUpdateHandler(), m_ignoreFilter, m_measureTime, m_modeOR, m_names, m_returnOK, m_shortCircuit, and membershipHandler().

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.

References ISequencerTimerTool::addTimer(), GaudiCommon< Algorithm >::debug(), decodeNames(), ISequencerTimerTool::decreaseIndent(), endreq(), GaudiCommon< Algorithm >::Error(), ISequencerTimerTool::globalTiming(), ISequencerTimerTool::increaseIndent(), GaudiAlgorithm::initialize(), StatusCode::isSuccess(), m_entries, m_measureTime, m_timer, m_timerTool, Algorithm::name(), Algorithm::release(), and StatusCode::SUCCESS.

00042                                       {
00043   GaudiAlgorithm::initialize();
00044 
00045   debug() << "==> Initialise" << endreq;
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.

References GaudiCommon< Algorithm >::debug(), endreq(), StatusCode::isSuccess(), m_entries, m_ignoreFilter, m_measureTime, m_modeOR, m_returnOK, m_shortCircuit, m_timer, m_timerTool, Algorithm::setExecuted(), Algorithm::setFilterPassed(), ISequencerTimerTool::start(), ISequencerTimerTool::stop(), and StatusCode::SUCCESS.

00082                                    {
00083 
00084   if ( m_measureTime ) m_timerTool->start( m_timer );
00085 
00086   debug() << "==> Execute" << endreq;
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_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.

References GaudiCommon< Algorithm >::debug(), endreq(), and GaudiAlgorithm::finalize().

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

StatusCode GaudiSequencer::beginRun (  )  [virtual]

Algorithm beginRun.

Reimplemented from Algorithm.

Definition at line 153 of file GaudiSequencer.cpp.

References GaudiCommon< Algorithm >::debug(), endreq(), Algorithm::isEnabled(), and StatusCode::SUCCESS.

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

StatusCode GaudiSequencer::endRun (  )  [virtual]

Algorithm endRun.

Reimplemented from Algorithm.

Definition at line 164 of file GaudiSequencer.cpp.

References GaudiCommon< Algorithm >::debug(), endreq(), Algorithm::isEnabled(), and StatusCode::SUCCESS.

00164                                     {
00165 
00166   if ( !isEnabled() ) return StatusCode::SUCCESS;
00167 
00168   debug() << "==> endRun" << endreq;
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.

References m_entries, and Algorithm::resetExecuted().

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.

References decodeNames(), StatusCode::ignore(), and Algorithm::isInitialized().

Referenced by GaudiSequencer().

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

StatusCode GaudiSequencer::decodeNames (  )  [protected]

Decode a vector of string.

Definition at line 186 of file GaudiSequencer.cpp.

References IJobOptionsSvc::addPropertyToCatalogue(), std::vector< _Tp, _Alloc >::begin(), GaudiCommon< Algorithm >::context(), Algorithm::createSubAlgorithm(), GaudiCommon< Algorithm >::debug(), std::vector< _Tp, _Alloc >::end(), endreq(), StatusCode::FAILURE, std::basic_string< _CharT, _Traits, _Alloc >::find_first_of(), IAlgManager::getAlgorithm(), IJobOptionsSvc::getProperties(), GaudiCommon< Algorithm >::globalTimeOffset(), StatusCode::ignore(), GaudiCommon< Algorithm >::info(), StatusCode::isSuccess(), m_entries, m_modeOR, m_names, GaudiCommon< Algorithm >::msg(), std::basic_string< _CharT, _Traits, _Alloc >::npos, Algorithm::release(), IJobOptionsSvc::removePropertyFromCatalogue(), GaudiCommon< Algorithm >::rootInTES(), std::basic_string< _CharT, _Traits, _Alloc >::substr(), StatusCode::SUCCESS, System::typeinfoName(), PropertyWithValue< TYPE >::value(), and GaudiCommon< Algorithm >::warning().

Referenced by initialize(), and membershipHandler().

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     std::string theName( *it );
00204     std::string theType( *it );
00205     std::string::size_type slash = it->find_first_of( '/' );
00206     if ( slash != std::string::npos ) {
00207       theType = it->substr( 0, slash );
00208       theName = it->substr( slash+1 );
00209     }
00210     //== handling of extensions to the name ???
00211 
00212     //== Check wether the specified algorithm already exists. If not, create it
00213 
00214     IAlgorithm* myIAlg;
00215     StatusCode result = appMgr->getAlgorithm( theName, myIAlg );
00216     if ( !result.isSuccess() ) {
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())
00266         myIAlg = myAlg;
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 );
00288       if (myAlg!=0) {
00289         m_entries.push_back( AlgorithmEntry( myAlg ) );
00290         myAlg->addRef();                  //== Indicate it is used.
00291         debug () << "Added algorithm " << theName << endreq;
00292       } else {
00293         warning() << theName << " is not an Algorithm - failed dynamic_cast"
00294                   << endreq;
00295         final = StatusCode::FAILURE;
00296       }
00297     } else {
00298       warning() << "Unable to find or create " << theName << endreq;
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 << endreq;
00325 
00326   return final;
00327 
00328 }

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

Private assignment operator: This is not allowed.


Member Data Documentation

StringArrayProperty GaudiSequencer::m_names [private]

Input string, list of algorithms.

Definition at line 72 of file GaudiSequencer.h.

Referenced by decodeNames(), and GaudiSequencer().

std::vector<AlgorithmEntry> GaudiSequencer::m_entries [private]

List of algorithms to process.

Definition at line 73 of file GaudiSequencer.h.

Referenced by decodeNames(), execute(), initialize(), and resetExecuted().

bool GaudiSequencer::m_modeOR [private]

Indicates that the OR is wanted instead of AND.

Definition at line 74 of file GaudiSequencer.h.

Referenced by decodeNames(), execute(), and GaudiSequencer().

bool GaudiSequencer::m_shortCircuit [private]

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

Definition at line 75 of file GaudiSequencer.h.

Referenced by execute(), and GaudiSequencer().

bool GaudiSequencer::m_ignoreFilter [private]

True if one continues always.

Definition at line 77 of file GaudiSequencer.h.

Referenced by execute(), and GaudiSequencer().

bool GaudiSequencer::m_isInitialized [private]

Indicate that we are ready.

Definition at line 78 of file GaudiSequencer.h.

bool GaudiSequencer::m_measureTime [private]

Flag to measure time.

Definition at line 79 of file GaudiSequencer.h.

Referenced by execute(), GaudiSequencer(), and initialize().

bool GaudiSequencer::m_returnOK [private]

Forces the sequencer to return a good status.

Definition at line 80 of file GaudiSequencer.h.

Referenced by execute(), and GaudiSequencer().

ISequencerTimerTool* GaudiSequencer::m_timerTool [private]

Pointer to the timer tool.

Definition at line 81 of file GaudiSequencer.h.

Referenced by execute(), and initialize().

int GaudiSequencer::m_timer [private]

Timer number for the sequencer.

Definition at line 82 of file GaudiSequencer.h.

Referenced by execute(), and initialize().


The documentation for this class was generated from the following files:
Generated at Fri Jul 18 12:07:37 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004