| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

GaudiSequencer.cpp

Go to the documentation of this file.
00001 // $Id: GaudiSequencer.cpp,v 1.18 2008/10/10 13:50:35 marcocle Exp $
00002 // Include files
00003 
00004 // from Gaudi
00005 #include "GaudiKernel/AlgFactory.h"
00006 #include "GaudiKernel/IAlgManager.h"
00007 #include "GaudiAlg/GaudiSequencer.h"
00008 #include "GaudiAlg/ISequencerTimerTool.h"
00009 #include "GaudiKernel/IJobOptionsSvc.h"
00010 
00011 //-----------------------------------------------------------------------------
00012 // Implementation file for class : GaudiSequencer
00013 //
00014 // 2004-05-13 : Olivier Callot
00015 //-----------------------------------------------------------------------------
00016 
00017 //=============================================================================
00018 // Standard constructor, initializes variables
00019 //=============================================================================
00020 GaudiSequencer::GaudiSequencer( const std::string& name,
00021                                 ISvcLocator* pSvcLocator)
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 }
00034 //=============================================================================
00035 // Destructor
00036 //=============================================================================
00037 GaudiSequencer::~GaudiSequencer() {};
00038 
00039 //=============================================================================
00040 // Initialisation. Check parameters
00041 //=============================================================================
00042 StatusCode GaudiSequencer::initialize() {
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 };
00078 
00079 //=============================================================================
00080 // Main execution
00081 //=============================================================================
00082 StatusCode GaudiSequencer::execute() {
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_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 };
00140 
00141 //=============================================================================
00142 //  Finalize
00143 //=============================================================================
00144 StatusCode GaudiSequencer::finalize() {
00145 
00146   debug() << "==> Finalize" << endreq;
00147   return  GaudiAlgorithm::finalize();
00148 }
00149 
00150 //=========================================================================
00151 //  Execute the beginRun of every algorithm
00152 //=========================================================================
00153 StatusCode GaudiSequencer::beginRun ( ) {
00154 
00155   if ( !isEnabled() ) return StatusCode::SUCCESS;
00156 
00157   debug() << "==> beginRun" << endreq;
00158   return StatusCode::SUCCESS;
00159 }
00160 
00161 //=========================================================================
00162 //  Execute the endRun() of every algorithm
00163 //=========================================================================
00164 StatusCode GaudiSequencer::endRun ( ) {
00165 
00166   if ( !isEnabled() ) return StatusCode::SUCCESS;
00167 
00168   debug() << "==> endRun" << endreq;
00169   return StatusCode::SUCCESS;
00170 }
00171 
00172 //=========================================================================
00173 // reset the executed status of all members
00174 //=========================================================================
00175 void GaudiSequencer::resetExecuted ( ) {
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 }
00183 //=========================================================================
00184 //  Decode the input names and fills the m_algs vector.
00185 //=========================================================================
00186 StatusCode GaudiSequencer::decodeNames( )  {
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 }
00329 
00330 //=========================================================================
00331 //  Interface for the Property manager
00332 //=========================================================================
00333 void GaudiSequencer::membershipHandler ( Property& ) {
00334   if ( isInitialized() ) decodeNames().ignore();
00335 }
00336 //=============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:58:14 2011 for GaudiAlg by doxygen 1.4.7