|
Gaudi Framework, version v23r4 |
| Home | Generated: Mon Sep 17 2012 |
Sequencer for executing several algorithms, stopping when one is faulty. More...
#include <GaudiSequencer.h>


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. | |
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.
Definition at line 27 of file GaudiSequencer.h.
| 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] |
| GaudiSequencer::GaudiSequencer | ( | const GaudiSequencer & | a ) | [private] |
Private copy, copy not allowed.
| 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();
}
}
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.