00001
00002
00003
00004
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
00013
00014
00015
00016
00017
00018
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
00036
00037 GaudiSequencer::~GaudiSequencer() {};
00038
00039
00040
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
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
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;
00091
00092
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;
00104
00105 }
00106
00107 if ( !m_ignoreFilter ) {
00108 bool passed = myAlg->filterPassed();
00109 if ( itE->reverse() ) passed = !passed;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
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
00143
00144 StatusCode GaudiSequencer::finalize() {
00145
00146 debug() << "==> Finalize" << endreq;
00147 return GaudiAlgorithm::finalize();
00148 }
00149
00150
00151
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
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
00174
00175 void GaudiSequencer::resetExecuted ( ) {
00176 Algorithm::resetExecuted();
00177
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
00185
00186 StatusCode GaudiSequencer::decodeNames( ) {
00187
00188 StatusCode final = StatusCode::SUCCESS;
00189 m_entries.clear();
00190
00191
00192 IJobOptionsSvc* jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
00193 bool addedContext = false;
00194 bool addedRootInTES = false;
00195 bool addedGlobalTimeOffset = false;
00196
00197
00198
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
00211
00212
00213
00214 IAlgorithm* myIAlg;
00215 StatusCode result = appMgr->getAlgorithm( theName, myIAlg );
00216 if ( !result.isSuccess() ) {
00217
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
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
00264
00265 if (result.isSuccess())
00266 myIAlg = myAlg;
00267 }
00268
00269
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
00284 if ( result.isSuccess() ) {
00285
00286
00287 Algorithm* myAlg = dynamic_cast<Algorithm*>( myIAlg );
00288 if (myAlg!=0) {
00289 m_entries.push_back( AlgorithmEntry( myAlg ) );
00290 myAlg->addRef();
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
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
00332
00333 void GaudiSequencer::membershipHandler ( Property& ) {
00334 if ( isInitialized() ) decodeNames().ignore();
00335 }
00336