| # Gaudi Framework, version v23r0 |

Home |  | Generated: Mon Jan 30 2012

Classes | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes

# 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.

## Classes
class | AlgorithmEntry
## 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.
GaudiSequencer & | operator= (const GaudiSequencer &a)
| Private assignment operator: This is not allowed.
## Private Attributes
StringArrayProperty | m_names
| Input string, list of algorithms.
std::vector< AlgorithmEntry > | m_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.
ISequencerTimerTool * | m_timerTool
| Pointer to the timer tool.
int | m_timer
| Timer number for the sequencer.

## Detailed Description

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

Default behaviour (ModeOR=False) is to execute all algorithms until one returns filterPassed() = False. If ShortCircuit is set to False, then all algorithms will be executed.

In OR mode, the logic is opposite. All algorithms until one returns filterPassed() = True. To then exit one must onter-intuitively set ShortCircuit to False. If the default value ShortCircuit=True is left then all algorithms will be executed.

Author:
  Olivier Callot

Date:
  2004-05-13

Definition at line 27 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.

      : GaudiAlgorithm ( name , pSvcLocator )
      , m_timerTool( 0 )
    {
      declareProperty( "Members"             , m_names                  );
      declareProperty( "ModeOR"              , m_modeOR         = false );
      declareProperty( "IgnoreFilterPassed"  , m_ignoreFilter   = false );
      declareProperty( "MeasureTime"         , m_measureTime    = false );
      declareProperty( "ReturnOK"            , m_returnOK       = false );
      declareProperty( "ShortCircuit"        , m_shortCircuit   = true  );

      m_names.declareUpdateHandler (& GaudiSequencer::membershipHandler, this );
    }

GaudiSequencer::~GaudiSequencer | ( | ) | `[virtual]`

Destructor.

Definition at line 37 of file GaudiSequencer.cpp.

    {}

GaudiSequencer::GaudiSequencer | ( | const GaudiSequencer & | a ) | `[private]`

Private copy, copy not allowed.

## Member Function Documentation

StatusCode GaudiSequencer::beginRun | ( | ) | `[virtual]`

Algorithm beginRun.

Reimplemented from Algorithm.

Definition at line 160 of file GaudiSequencer.cpp.

                                          {

      if ( !isEnabled() ) return StatusCode::SUCCESS;

      if (msgLevel(MSG::DEBUG)) debug() << "==> beginRun" << endmsg;
      return StatusCode::SUCCESS;
    }

StatusCode GaudiSequencer::decodeNames | ( | ) | `[protected]`

Decode a vector of string.

Definition at line 199 of file GaudiSequencer.cpp.

                                             {

      StatusCode final = StatusCode::SUCCESS;
      m_entries.clear();

      //== Get the "Context" option if in the file...
      IJobOptionsSvc* jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
      bool addedContext = false;  //= Have we added the context ?
      bool addedRootInTES = false;  //= Have we added the rootInTES ?
      bool addedGlobalTimeOffset = false;  //= Have we added the globalTimeOffset ?

      //= Get the Application manager, to see if algorithm exist
      IAlgManager* appMgr = svc<IAlgManager>("ApplicationMgr");
      const std::vector<std::string>& nameVector = m_names.value();
      std::vector<std::string>::const_iterator it;
      for ( it = nameVector.begin(); nameVector.end() != it; it++ ) {
        const Gaudi::Utils::TypeNameString typeName(*it);
        const std::string &theName = typeName.name();
        const std::string &theType = typeName.type();

        //== Check wether the specified algorithm already exists. If not, create it
        StatusCode result = StatusCode::SUCCESS;
        SmartIF<IAlgorithm> myIAlg = appMgr->algorithm(typeName, false); // do not create it now
        if ( !myIAlg.isValid() ) {
          //== Set the Context if not in the jobOptions list
          if ( ""  != context() ||
               ""  != rootInTES() ||
               0.0 != globalTimeOffset() ) {
            bool foundContext = false;
            bool foundRootInTES = false;
            bool foundGlobalTimeOffset = false;
            const std::vector<const Property*>* properties = jos->getProperties( theName );
            if ( 0 != properties ) {
              // Iterate over the list to set the options
              for ( std::vector<const Property*>::const_iterator itProp = properties->begin();
                   itProp != properties->end();
                   itProp++ )   {
                const StringProperty* sp = dynamic_cast<const StringProperty*>(*itProp);
                if ( 0 != sp )    {
                  if ( "Context" == (*itProp)->name() ) {
                    foundContext = true;
                  }
                  if ( "RootInTES" == (*itProp)->name() ) {
                    foundRootInTES = true;
                  }
                  if ( "GlobalTimeOffset" == (*itProp)->name() ) {
                    foundGlobalTimeOffset = true;
                  }
                }
              }
            }
            if ( !foundContext && "" != context() ) {
              StringProperty contextProperty( "Context", context() );
              jos->addPropertyToCatalogue( theName, contextProperty ).ignore();
              addedContext = true;
            }
            if ( !foundRootInTES && "" != rootInTES() ) {
              StringProperty rootInTESProperty( "RootInTES", rootInTES() );
              jos->addPropertyToCatalogue( theName, rootInTESProperty ).ignore();
              addedRootInTES = true;
            }
            if ( !foundGlobalTimeOffset && 0.0 != globalTimeOffset() ) {
              DoubleProperty globalTimeOffsetProperty( "GlobalTimeOffset", globalTimeOffset() );
              jos->addPropertyToCatalogue( theName, globalTimeOffsetProperty ).ignore();
              addedGlobalTimeOffset = true;
            }
          }

          Algorithm *myAlg = 0;
          result = createSubAlgorithm( theType, theName, myAlg );
          // (MCl) this should prevent bug #35199... even if I didn't manage to
          // reproduce it with a simple test.
          if (result.isSuccess()) myIAlg = myAlg;
        } else {
          Algorithm *myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
          if (myAlg) {
            subAlgorithms()->push_back(myAlg);
            // when the algorithm is not created, the ref count is short by one, so we have to fix it.
            myAlg->addRef();
          }
        }

        //== Remove the property, in case this is not a GaudiAlgorithm...
        if ( addedContext ) {
          jos->removePropertyFromCatalogue( theName, "Context" ).ignore();
          addedContext = false;
        }
        if ( addedRootInTES ) {
          jos->removePropertyFromCatalogue( theName, "RootInTES" ).ignore();
          addedRootInTES = false;
        }
        if ( addedGlobalTimeOffset ) {
          jos->removePropertyFromCatalogue( theName, "GlobalTimeOffset" ).ignore();
          addedGlobalTimeOffset = false;
        }

        // propagate the sub-algorithm into own state.
        if ( result.isSuccess () &&
             Gaudi::StateMachine::INITIALIZED <= FSMState() &&
             myIAlg.isValid   () &&
             Gaudi::StateMachine::INITIALIZED  > myIAlg->FSMState() )
        {
          StatusCode sc = myIAlg->sysInitialize() ;
          if  ( sc.isFailure() ) { result = sc ; }
        }

        // propagate the sub-algorithm into own state.
        if ( result.isSuccess () &&
             Gaudi::StateMachine::RUNNING <= FSMState() &&
             myIAlg.isValid   () &&
             Gaudi::StateMachine::RUNNING  > myIAlg->FSMState() )
        {
          StatusCode sc = myIAlg->sysStart () ;
          if  ( sc.isFailure() ) { result = sc ; }
        }

        //== Is it an Algorithm ?  Strange test...
        if ( result.isSuccess() ) {
          // TODO: (MCl) it is possible to avoid the dynamic_cast in most of the
          //             cases by keeping the result of createSubAlgorithm.
          Algorithm*  myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
          if (myAlg!=0) {
            // Note: The reference counting is kept by the system of sub-algorithms
            m_entries.push_back( AlgorithmEntry( myAlg ) );
            if (msgLevel(MSG::DEBUG)) debug () << "Added algorithm " << theName << endmsg;
          } else {
            warning() << theName << " is not an Algorithm - failed dynamic_cast"
                      << endmsg;
            final = StatusCode::FAILURE;
          }
        } else {
          warning() << "Unable to find or create " << theName << endmsg;
          final = result;
        }

      }

      release(appMgr).ignore();
      release(jos).ignore();

      //== Print the list of algorithms
      MsgStream& msg = info();
      if ( m_modeOR ) msg << "OR ";
      msg << "Member list: ";
      std::vector<AlgorithmEntry>::iterator itE;
      for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
        Algorithm* myAlg = (*itE).algorithm();
        std::string myAlgType = System::typeinfoName( typeid( *myAlg) ) ;
        if ( myAlg->name() == myAlgType ) {
          msg << myAlg->name();
        } else {
          msg << myAlgType << "/" << myAlg->name();
        }
        if ( itE+1 != m_entries.end() ) msg << ", ";
      }
      if ( "" != context() ) msg << ", with context '" << context() << "'";
      if ( "" != rootInTES() ) msg << ", with rootInTES '" << rootInTES() << "'";
      if ( 0.0 != globalTimeOffset() ) msg << ", with globalTimeOffset " << globalTimeOffset();
      msg << endmsg;

      return final;

    }

StatusCode GaudiSequencer::endRun | ( | ) | `[virtual]`

Algorithm endRun.

Reimplemented from Algorithm.

Definition at line 171 of file GaudiSequencer.cpp.

                                        {

      if ( !isEnabled() ) return StatusCode::SUCCESS;

      if (msgLevel(MSG::DEBUG)) debug() << "==> endRun" << endmsg;
      return StatusCode::SUCCESS;
    }

StatusCode GaudiSequencer::execute | ( | ) | `[virtual]`

Algorithm execution.

Reimplemented from GaudiAlgorithm.

Definition at line 82 of file GaudiSequencer.cpp.

                                       {

      if ( m_measureTime ) m_timerTool->start( m_timer );

      if (msgLevel(MSG::DEBUG)) debug() << "==> Execute" << endmsg;

      StatusCode result = StatusCode::SUCCESS;

      bool seqPass = !m_modeOR; //  for OR, result will be false, unless (at least) one is true
                                //  for AND, result will be true, unless (at least) one is false
                                //    also see comment below ....

      std::vector<AlgorithmEntry>::const_iterator itE;
      for ( itE = m_entries.begin(); m_entries.end() != itE; ++itE ) {
        Algorithm* myAlg = itE->algorithm();
        if ( ! myAlg->isEnabled() ) continue;
        if ( ! myAlg->isExecuted() ) {
          if ( m_measureTime ) m_timerTool->start( itE->timer() );
          result = myAlg->sysExecute();
          if ( m_measureTime ) m_timerTool->stop( itE->timer() );
          myAlg->setExecuted( true );
          if ( ! result.isSuccess() ) break;  //== Abort and return bad status
        }
        //== Check the returned status
        if ( !m_ignoreFilter ) {
          bool passed = myAlg->filterPassed();
          if (msgLevel(MSG::VERBOSE))
            verbose() << "Algorithm " << myAlg->name() << " returned filter passed "
                      << (passed ? "true" : "false") << endmsg;
          if ( itE->reverse() ) passed = !passed;

          //== indicate our own result. For OR, exit as soon as true.
          //        If no more, will exit with false.
          //== for AND, exit as soon as false. Else, will be true (default)

          // if not short-circuiting, make sure we latch iPass to 'true' in
          // OR mode (i.e. it is sufficient for one item to be true in order
          // to be true at the end, and thus we start out at 'false'), and latch
          // to 'false' in AND mode (i.e. it is sufficient for one item to
          // be false to the false in the end, and thus we start out at 'true')
          // -- i.e. we should not just blindly return the 'last' passed status!

          // or to put it another way: in OR mode, we don't care about things
          // which are false, as they leave our current state alone (provided
          // we stared as 'false'!), and in AND mode, we keep our current
          // state until someone returns 'false' (provided we started as 'true')
          if ( m_modeOR ? passed : !passed ) {
            seqPass = passed;
            if (msgLevel(MSG::VERBOSE))
              verbose() << "SeqPass is now " << (seqPass ? "true" : "false") << endmsg;
            if (m_shortCircuit) break;
          }
        }

      }
      if (msgLevel(MSG::VERBOSE))
          verbose() << "SeqPass is " << (seqPass ? "true" : "false") << endmsg;
      if ( !m_ignoreFilter && !m_entries.empty() ) setFilterPassed( seqPass );
      setExecuted( true );

      if ( m_measureTime ) m_timerTool->stop( m_timer );

      return m_returnOK ? StatusCode::SUCCESS : result;
    }

StatusCode GaudiSequencer::finalize | ( | ) | `[virtual]`

Algorithm finalization.

Reimplemented from GaudiAlgorithm.

Definition at line 151 of file GaudiSequencer.cpp.

                                        {

      if (msgLevel(MSG::DEBUG)) debug() << "==> Finalize" << endmsg;
      return  GaudiAlgorithm::finalize();
    }

StatusCode GaudiSequencer::initialize | ( | ) | `[virtual]`

Algorithm initialization.

Reimplemented from GaudiAlgorithm.

Definition at line 42 of file GaudiSequencer.cpp.

                                          {
      GaudiAlgorithm::initialize();

      if (msgLevel(MSG::DEBUG)) debug() << "==> Initialise" << endmsg;

      StatusCode status = decodeNames();
      if ( !status.isSuccess() ) return status;

      m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" );
      if ( m_timerTool->globalTiming() ) m_measureTime = true;

      if ( m_measureTime ) {
        m_timer = m_timerTool->addTimer( name() );
        m_timerTool->increaseIndent();
      } else {
        release( m_timerTool );
        m_timerTool = 0;
      }

      //== Initialize the algorithms
      std::vector<AlgorithmEntry>::iterator itE;
      for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
        if ( m_measureTime ) {
          itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
        }

        status = itE->algorithm()->sysInitialize();
        if ( !status.isSuccess() ) {
          return Error( "Can not initialize " + itE->algorithm()->name(),
                        status );
        }
      }
      if ( m_measureTime ) m_timerTool->decreaseIndent();

      return StatusCode::SUCCESS;
    }

void GaudiSequencer::membershipHandler | ( | Property & | theProp ) |

for asynchronous changes in the list of algorithms

Definition at line 371 of file GaudiSequencer.cpp.

    {
      // no action for not-yet initialized sequencer
      if ( Gaudi::StateMachine::INITIALIZED > FSMState() ) { return ; } // RETURN

      decodeNames().ignore();

      if  ( !m_measureTime ) { return ; }                                // RETURN

      // add the entries into timer table:

      if ( 0 == m_timerTool )
      { m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" ) ; }

      if ( m_timerTool->globalTiming() ) m_measureTime = true;

      m_timer = m_timerTool->addTimer( name() );
      m_timerTool->increaseIndent();

      for ( std::vector<AlgorithmEntry>::iterator itE = m_entries.begin() ;
            m_entries.end() != itE; ++itE )
      {
        itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
      }

      m_timerTool->decreaseIndent();

    }

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

Private assignment operator: This is not allowed.

void GaudiSequencer::resetExecuted | ( | ) | `[virtual]`

Called before an event processing.

Reimplemented from Algorithm.

Definition at line 182 of file GaudiSequencer.cpp.

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

## Member Data Documentation

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

List of algorithms to process.

Definition at line 82 of file GaudiSequencer.h.

bool GaudiSequencer::m_ignoreFilter`[private]`

True if one continues always.

Definition at line 87 of file GaudiSequencer.h.

bool GaudiSequencer::m_isInitialized`[private]`

Indicate that we are ready.

Definition at line 88 of file GaudiSequencer.h.

bool GaudiSequencer::m_measureTime`[private]`

Flag to measure time.

Definition at line 89 of file GaudiSequencer.h.

bool GaudiSequencer::m_modeOR`[private]`

Indicates that the OR is wanted instead of AND.

Definition at line 83 of file GaudiSequencer.h.

StringArrayProperty GaudiSequencer::m_names`[private]`

Input string, list of algorithms.

Definition at line 81 of file GaudiSequencer.h.

bool GaudiSequencer::m_returnOK`[private]`

Forces the sequencer to return a good status.

Definition at line 90 of file GaudiSequencer.h.

bool GaudiSequencer::m_shortCircuit`[private]`

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

In MOdeOR=True the behaviour is the exact opposite.

Definition at line 84 of file GaudiSequencer.h.

int GaudiSequencer::m_timer`[private]`

Timer number for the sequencer.

Definition at line 92 of file GaudiSequencer.h.

ISequencerTimerTool* GaudiSequencer::m_timerTool`[private]`

Pointer to the timer tool.

Definition at line 91 of file GaudiSequencer.h.

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

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v23r0/GaudiAlg/GaudiAlg/GaudiSequencer.h
- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v23r0/GaudiAlg/src/lib/GaudiSequencer.cpp

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines