Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Sequencer.cpp

Go to the documentation of this file.
00001 //$Header: /nfs/slac/g/glast/ground/cvs/GaudiAlg/src/Sequencer.cpp,v 1.1.1.1 2001/04/18 21:03:30 tlindner Exp $
00002 
00003 // Sequencer class
00004 // Implements:
00005 // 1) Common functionality of IInterface
00006 // 2) Default behaviour for the IAlgorithm
00007 //
00008 
00009 #include "Sequencer.h"
00010 
00011 #include "GaudiKernel/IAlgManager.h"
00012 #include "GaudiKernel/ISvcLocator.h"
00013 #include "GaudiKernel/AlgFactory.h"
00014 #include "GaudiKernel/MsgStream.h"
00015 #include "GaudiKernel/Chrono.h"
00016 #include "GaudiKernel/Stat.h"
00017 #include "GaudiKernel/GaudiException.h"
00018 
00019 static const AlgFactory<Sequencer>    Factory;
00020 const IAlgFactory& SequencerFactory = Factory;
00021 
00025 Sequencer::Sequencer( const std::string& name, ISvcLocator* pSvcLocator )
00026 : Algorithm( name, pSvcLocator ),
00027   m_branchFilterPassed( false )
00028 {
00029 
00030     // Create vector of branch algorithms
00031     m_branchAlgs = new std::vector<Algorithm*>();
00032 
00033     // Declare Sequencer properties with their defaults
00034     declareProperty( "Members", m_names );
00035     declareProperty( "BranchMembers", m_branchNames );
00036     declareProperty( "StopOverride", m_stopOverride=false );
00037 
00038     // Associate action handlers with the "Members" and "BranchMembers" properties
00039     m_names.declareUpdateHandler      ( &Sequencer::membershipHandler      , this );
00040     m_branchNames.declareUpdateHandler( &Sequencer::branchMembershipHandler, this );
00041 
00042 }
00043 
00047 Sequencer::~Sequencer()
00048 {
00049     delete m_branchAlgs;
00050 }
00051 
00052 StatusCode
00053 Sequencer::initialize()
00054 {
00055     StatusCode result;
00056 
00057     // Set the initialized state. This allows the membership handlers
00058     // to operate correctly since they are prevented from doing anything
00059     // until this state is reached.
00060     setInitialized( );
00061 
00062     // Build the main membership
00063     result = decodeMemberNames( );
00064     if ( result.isSuccess( ) ) {
00065 
00066         // Build the branch membership
00067         result = decodeBranchMemberNames( );
00068     }
00069     return result;
00070 }
00071 
00072 StatusCode
00073 Sequencer::execute()
00074 {
00075     StatusCode result = StatusCode::SUCCESS;
00076     MsgStream log( msgSvc( ), name( ) );
00077 
00078     log << MSG::DEBUG << name( ) << " Sequencer::execute( )" << endreq;
00079 
00080     // Bypass the loop if this sequencer is disabled or has already been executed
00081     if ( isEnabled( ) && ! isExecuted( ) ) {
00082         Algorithm* lastAlgorithm;
00083         result = execute( subAlgorithms( ), m_isInverted, lastAlgorithm );
00084         if ( result.isSuccess( ) ) {
00085             bool passed = filterPassed( );
00086             if ( ! passed && ! isStopOverride( ) ) {
00087 
00088                 // Filter failed and stop override not set. Execute the
00089                 // branch if there is one associated with the filter
00090                 // algorithm that failed. Note that the first member on
00091                 // the branch is the failing algorithm and so should
00092                 // be skipped.
00093                 std::vector<Algorithm*>* theAlgs = branchAlgorithms( );
00094                 if ( theAlgs->size( ) > 0 ) {
00095                     Algorithm* branchAlgorithm = (*theAlgs)[0];
00096                     if ( lastAlgorithm == branchAlgorithm ) {
00097 
00098                         // Branch specified - Loop over branch members
00099                         result = execute( branchAlgorithms( ),
00100                                           m_isBranchInverted,
00101                                           lastAlgorithm, 1 );
00102                         if ( result.isSuccess( ) ) {
00103 
00104                             // The final filter passed state will be set true if either
00105                             // of the main or branches passed, otherwise false.
00106 
00107                             // Save the branch  filter passed state.
00108                             setBranchFilterPassed( filterPassed( ) );
00109                         }
00110                     }
00111                 }
00112             }
00113         }
00114 
00115         // Prevent multiple executions of this sequencer for the current event
00116         setExecuted( true );
00117    }
00118     return result;
00119 }
00120 
00121 StatusCode
00122 Sequencer::finalize()
00123 {
00124     // Loop over all branch members calling their finalize functions
00125     // if they are not disabled. Note that the Algoriithm::sysFinalize
00126     // function already does this for the main members.
00127     std::vector<Algorithm*>* subAlgms = branchAlgorithms( );
00128     std::vector<Algorithm*>::iterator it;
00129     std::vector<Algorithm*>::iterator itend = subAlgms->end( );
00130     for (it = subAlgms->begin(); it != itend; it++) {
00131         Algorithm* theAlgorithm = (*it);
00132         theAlgorithm->sysFinalize( );
00133     }
00134     return StatusCode::SUCCESS;
00135 }
00136 
00137 StatusCode
00138 Sequencer::resetExecuted( )
00139 {
00140     Algorithm::resetExecuted( );
00141 
00142     // Loop over all members calling their resetExecuted functions
00143     // if they are not disabled.
00144     std::vector<Algorithm*>* subAlgms = subAlgorithms( );
00145     std::vector<Algorithm*>::iterator it;
00146     std::vector<Algorithm*>::iterator itend = subAlgms->end( );
00147     for (it = subAlgms->begin(); it != itend; it++) {
00148         Algorithm* theAlgorithm = (*it);
00149         theAlgorithm->resetExecuted( );
00150     }
00151 
00152     // Loop over all branch members calling their resetExecuted functions
00153     // if they are not disabled.
00154     subAlgms = branchAlgorithms( );
00155     itend    = subAlgms->end( );
00156     for (it = subAlgms->begin(); it != itend; it++) {
00157         Algorithm* theAlgorithm = (*it);
00158         theAlgorithm->resetExecuted( );
00159     }
00160 
00161     // Reset the branch filter passed flag
00162     m_branchFilterPassed = false;
00163     return StatusCode::SUCCESS;
00164 }
00165 
00166 bool
00167 Sequencer::branchFilterPassed( ) const
00168 {
00169     return m_branchFilterPassed;
00170 }
00171 
00172 StatusCode
00173 Sequencer::setBranchFilterPassed( bool state )
00174 {
00175     m_branchFilterPassed = state;
00176     return StatusCode::SUCCESS;
00177 }
00178 
00179 bool
00180 Sequencer::isStopOverride( ) const
00181 {
00182     return m_stopOverride.value( );
00183 }
00184 
00185 StatusCode
00186 Sequencer::append( Algorithm* pAlgorithm )
00187 {
00188     StatusCode result = append( pAlgorithm, subAlgorithms( ) );
00189     return result;
00190 }
00191 
00192 StatusCode
00193 Sequencer::appendToBranch( Algorithm* pAlgorithm )
00194 {
00195     StatusCode result = append( pAlgorithm, branchAlgorithms( ) );
00196     return result;
00197 }
00198 
00199 StatusCode
00200 Sequencer::createAndAppend( const std::string& type,
00201                             const std::string& name,
00202                                             Algorithm*& pAlgorithm )
00203 {
00204     StatusCode result = createAndAppend( type, name, pAlgorithm, subAlgorithms( ) );
00205     return result;
00206 }
00207 
00208 StatusCode
00209 Sequencer::createAndAppendToBranch( const std::string& type,
00210                                     const std::string& name,
00211                                                     Algorithm*& pAlgorithm )
00212 {
00213     StatusCode result = createAndAppend( type, name, pAlgorithm, branchAlgorithms( ) );
00214     return result;
00215 }
00216 
00217 StatusCode
00218 Sequencer::remove( Algorithm* pAlgorithm )
00219 {
00220     std::string theName = pAlgorithm->name( );
00221     StatusCode result = remove( theName );
00222     return result;
00223 }
00224 
00225 StatusCode
00226 Sequencer::remove( const std::string& algname )
00227 {
00228     StatusCode result = remove( algname, subAlgorithms( ) );
00229     return result;
00230 }
00231 
00232 StatusCode
00233 Sequencer::removeFromBranch( Algorithm* pAlgorithm )
00234 {
00235     std::string theName = pAlgorithm->name( );
00236     StatusCode result = removeFromBranch( theName );
00237     return result;
00238 }
00239 
00240 StatusCode
00241 Sequencer::removeFromBranch( const std::string& algname )
00242 {
00243     StatusCode result = remove( algname, branchAlgorithms( ) );
00244     return result;
00245 }
00246 
00247 std::vector<Algorithm*>*
00248 Sequencer::branchAlgorithms( ) const {
00249     return m_branchAlgs;
00250 }
00251 
00252 StatusCode
00253 Sequencer::decodeMemberNames( )
00254 {
00255     StatusCode result = StatusCode::SUCCESS;
00256 
00257     // Don't do anything if the Sequencer isn't yet initialized
00258     if ( isInitialized( ) ) {
00259 
00260         // Decode the membership list
00261         result = decodeNames( m_names, subAlgorithms( ), m_isInverted );
00262     }
00263     return result;
00264 }
00265 
00266 void
00267 Sequencer::membershipHandler( Property& /* theProp */ )
00268 {
00269     decodeMemberNames( );
00270 }
00271 
00272 StatusCode
00273 Sequencer::decodeBranchMemberNames( )
00274 {
00275     StatusCode result = StatusCode::SUCCESS;
00276 
00277     // Don't do anything if the Sequencer isn't yet initialized
00278     if ( isInitialized( ) ) {
00279 
00280         // Decode the branch membership list
00281         result = decodeNames( m_branchNames,
00282                               branchAlgorithms( ),
00283                               m_isBranchInverted );
00284 
00285     }
00286     return result;
00287 }
00288 
00289 void
00290 Sequencer::branchMembershipHandler( Property& /* theProp */ )
00291 {
00292     decodeBranchMemberNames( );
00293 }
00294 
00299 StatusCode
00300 Sequencer::append( Algorithm* pAlgorithm,
00301                    std::vector<Algorithm*>* theAlgs )
00302 {
00303     StatusCode result = StatusCode::SUCCESS;
00304 
00305     // Check that the specified algorithm doesn't already exist in the membership list
00306     std::vector<Algorithm*>::iterator it;
00307     std::vector<Algorithm*>::iterator itend = theAlgs->end( );
00308     for (it = theAlgs->begin(); it != itend; it++) {
00309         Algorithm* theAlgorithm = (*it);
00310         if ( theAlgorithm == pAlgorithm ) {
00311             result = StatusCode::FAILURE;
00312             break;
00313         }
00314     }
00315     if ( result.isSuccess( ) ) {
00316         theAlgs->push_back( pAlgorithm );
00317     }
00318     return result;
00319 }
00320 
00321 StatusCode
00322 Sequencer::createAndAppend( const std::string& type,
00323                                 const std::string& name,
00324                                 Algorithm*& pAlgorithm,
00325                                 std::vector<Algorithm*>* theAlgs )
00326 {
00327     StatusCode result = StatusCode::FAILURE;
00328     IAlgManager* theAlgMgr;
00329     result = serviceLocator( )->getService( "ApplicationMgr",
00330                                             IID_IAlgManager,
00331                                             (IInterface*&)theAlgMgr );
00332     if ( result.isSuccess( ) ) {
00333 
00334             IAlgorithm* tmp;
00335         result = theAlgMgr->createAlgorithm( type, name, tmp );
00336         if ( result.isSuccess( ) ) {
00337                 try{
00338                         pAlgorithm = dynamic_cast<Algorithm*>(tmp);
00339                         theAlgs->push_back( pAlgorithm );       
00340                 } catch(...){
00341                         result = StatusCode::FAILURE;
00342                     }
00343         }
00344         }
00345         return result;
00346 }
00347 
00348 StatusCode
00349 Sequencer::decodeNames( StringArrayProperty& theNames,
00350                         std::vector<Algorithm*>* theAlgs,
00351                         std::vector<bool>& theLogic )
00352 {
00353     StatusCode result;
00354     MsgStream log( msgSvc( ), name( ) );
00355     IAlgManager* theAlgMgr;
00356     result = serviceLocator( )->getService( "ApplicationMgr",
00357                                             IID_IAlgManager,
00358                                             (IInterface*&)theAlgMgr );
00359     if ( result.isSuccess( ) ) {
00360 
00361         // Clear the existing list of algorithms
00362         theAlgs->clear( );
00363 
00364         // Build the list of member algorithms from the contents of the
00365         // theNames list.
00366         const std::vector<std::string>& theNameVector = theNames.value( );
00367         std::vector<std::string>::const_iterator it;
00368         std::vector<std::string>::const_iterator itend = theNameVector.end( );
00369         for (it = theNameVector.begin(); it != itend; it++) {
00370 
00371             // Parse the name for a syntax of the form:
00372             //
00373             // <type>/<name>
00374             //
00375             // Where <name> is the algorithm instance name, and <type> is the
00376             // algorithm class type (being a subclass of Algorithm).
00377             std::string theName = (*it);
00378             std::string theType = (*it);
00379             int slash = (*it).find_first_of( "/" );
00380             if ( slash > 0 ) {
00381                 theType = (*it).substr( 0, slash );
00382                 theName = (*it).substr( slash+1 );
00383             }
00384 
00385             // Parse the name for a syntax of the form:
00386             //
00387             // <name>:invert
00388             //
00389             // Where <name> is the algorithm instance name and ":invert"
00390             // indicates that the filter passed logic is inverted.
00391             bool isInverted = false;
00392             int invert    = theName.find_first_of( ":" );
00393             if ( invert > 0 ) {
00394                 theName = theName.substr( 0, invert );
00395                 isInverted = true;
00396             }
00397             // Check whether the suppied name corresponds to an existing
00398             // Algorithm object.
00399             IAlgorithm* theIAlg;
00400             Algorithm*  theAlgorithm;
00401             StatusCode status = theAlgMgr->getAlgorithm( theName, theIAlg );
00402             if ( status.isSuccess( ) ) {
00403                     try{
00404                             theAlgorithm = dynamic_cast<Algorithm*>(theIAlg);
00405                     } catch(...){
00406                             status = StatusCode::FAILURE;
00407                     }
00408                 }
00409             if ( status.isSuccess( ) ) {
00410 
00411                 // The specified Algorithm already exists - just append it to the membership list.
00412                 status = append( theAlgorithm, theAlgs );
00413                 if ( status.isSuccess( ) ) {
00414                     log << MSG::INFO << theName << " already exists - appended to member list" << endreq;
00415                 } else {
00416                     log << MSG::INFO << theName << " already exists - append failed!!!" << endreq;
00417                 }
00418             } else {
00419 
00420                 // The specified name doesn't exist - create a new object of the specified type
00421                 // and append it to the membership list.
00422                 status = createAndAppend( theType, theName, theAlgorithm, theAlgs );
00423                 if ( status.isSuccess( ) ) {
00424                     log << MSG::INFO << theName << " doesn't exist - created and appended to member list" << endreq;
00425                 } else {
00426                     log << MSG::INFO << theName << " doesn't exist - creation failed!!!" << endreq;
00427                 }
00428             }
00429             if ( status.isSuccess( ) ) {
00430                 theLogic.push_back( isInverted );
00431             }
00432         }
00433 
00434         // Loop over all the membership list calling their initialize functions
00435         // if they are not disabled. Note that the Algoriithm::sysInitialize
00436         // function protects this from affecting Algorithms that have already
00437         // been initialized.
00438         std::vector<Algorithm*>::iterator ait;
00439         std::vector<Algorithm*>::iterator aitend = theAlgs->end( );
00440         for (ait = theAlgs->begin(); ait != aitend; ait++) {
00441             Algorithm* theAlgorithm = (*ait);
00442             theAlgorithm->sysInitialize( );
00443         }
00444 
00445     }
00446     return result;
00447 }
00448 
00449 StatusCode
00450 Sequencer::execute( std::vector<Algorithm*>* theAlgs,
00451                     std::vector<bool>& theLogic,
00452                     Algorithm*& lastAlgorithm,
00453                     unsigned int first )
00454 {
00455     StatusCode result = StatusCode::SUCCESS;
00456 
00457     // Loop over all algorithms calling their execute functions if they
00458     // are (a) not disabled, and (b) aren't already executed. Note that
00459     // in the latter case the filter state is still examined. Terminate
00460     // the loop if an algorithm indicates that it's filter didn't pass.
00461     unsigned int size = theAlgs->size( );
00462     for (unsigned int i = first; i < size; i++) {
00463         lastAlgorithm = (*theAlgs)[i];
00464         result = executeMember( lastAlgorithm );
00465         if ( result.isSuccess( ) ) {
00466 
00467             // Take the filter passed status of this algorithm as my own status.
00468             // Note that we take into account inverted logic.
00469             bool passed = lastAlgorithm->filterPassed( );
00470             bool isInverted = theLogic[i];
00471             if ( isInverted ) {
00472                 passed = ! passed;
00473             }
00474             setFilterPassed( passed );
00475 
00476             // The behaviour when the filter fails depends on the StopOverride property.
00477             // The default action is to stop processing, but this default can be
00478             // overridden by setting the "StopOverride" property to true.
00479             if ( ! isStopOverride( ) ) {
00480                 if ( ! passed ) break;
00481             }
00482         } else {
00483             break;
00484         }
00485     }
00486     return result;
00487 }
00488 
00489 StatusCode
00490 Sequencer::executeMember( Algorithm* theAlgorithm )
00491 {
00492     StatusCode result = StatusCode::SUCCESS;
00493     if ( theAlgorithm->isEnabled( ) ) {
00494         if ( ! theAlgorithm->isExecuted( ) ) {
00495             result = theAlgorithm->sysExecute( );
00496 
00497             // Set the executed state of the algorithm.
00498             // I think this should be done by the algorithm itself, but just in case...
00499             theAlgorithm->setExecuted( true );
00500         }
00501     }
00502     return result;
00503 }
00504 
00505 StatusCode
00506 Sequencer::remove( const std::string& algname, std::vector<Algorithm*>* theAlgs )
00507 {
00508     MsgStream log( msgSvc( ), name( ) );
00509     StatusCode result = StatusCode::FAILURE;
00510 
00511     // Test that the algorithm exists in the member list
00512     std::vector<Algorithm*>::iterator it;
00513     std::vector<Algorithm*>::iterator itend = theAlgs->end( );
00514     for (it = theAlgs->begin(); it != itend; it++) {
00515         Algorithm* theAlgorithm = (*it);
00516         if ( theAlgorithm->name( ) == algname ) {
00517 
00518             // Algorithm with specified name exists in the algorithm list - remove it
00519             // THIS ISN'T IMPLEMENTED YET!!!!
00520             log << MSG::INFO <<"Sequencer::remove( ) isn't implemented yet!!!!!" << endreq;
00521             result = StatusCode::SUCCESS;
00522             break;
00523         }
00524     }
00525     return result;
00526 }

Generated at Wed Nov 21 12:20:23 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000