Gaudi Framework, version v25r2

Home   Generated: Wed Jun 4 2014
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GaudiSequencer.cpp
Go to the documentation of this file.
1 // Include files
2 
3 // from Gaudi
8 
9 //-----------------------------------------------------------------------------
10 // Implementation file for class : GaudiSequencer
11 //
12 // 2004-05-13 : Olivier Callot
13 //-----------------------------------------------------------------------------
14 
15 //=============================================================================
16 // Standard constructor, initializes variables
17 //=============================================================================
18 GaudiSequencer::GaudiSequencer( const std::string& name,
19  ISvcLocator* pSvcLocator)
20  : GaudiAlgorithm ( name , pSvcLocator )
21  , m_timerTool( 0 )
22 {
23  declareProperty( "Members" , m_names );
24  declareProperty( "ModeOR" , m_modeOR = false );
25  declareProperty( "IgnoreFilterPassed" , m_ignoreFilter = false );
26  declareProperty( "MeasureTime" , m_measureTime = false );
27  declareProperty( "ReturnOK" , m_returnOK = false );
28  declareProperty( "ShortCircuit" , m_shortCircuit = true );
29 
31 }
32 //=============================================================================
33 // Destructor
34 //=============================================================================
36 
37 //=============================================================================
38 // Initialisation. Check parameters
39 //=============================================================================
42 
43  if (msgLevel(MSG::DEBUG)) debug() << "==> Initialise" << endmsg;
44 
45  StatusCode status = decodeNames();
46  if ( !status.isSuccess() ) return status;
47 
48  m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" );
49  if ( m_timerTool->globalTiming() ) m_measureTime = true;
50 
51  if ( m_measureTime ) {
54  } else {
56  m_timerTool = 0;
57  }
58 
59  //== Initialize the algorithms
60  std::vector<AlgorithmEntry>::iterator itE;
61  for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
62  if ( m_measureTime ) {
63  itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
64  }
65 
66  status = itE->algorithm()->sysInitialize();
67  if ( !status.isSuccess() ) {
68  return Error( "Can not initialize " + itE->algorithm()->name(),
69  status );
70  }
71  }
73 
74  return StatusCode::SUCCESS;
75 }
76 
77 //=============================================================================
78 // Main execution
79 //=============================================================================
81 
83 
84  if (msgLevel(MSG::DEBUG)) debug() << "==> Execute" << endmsg;
85 
87 
88  bool seqPass = !m_modeOR; // for OR, result will be false, unless (at least) one is true
89  // for AND, result will be true, unless (at least) one is false
90  // also see comment below ....
91 
92  std::vector<AlgorithmEntry>::const_iterator itE;
93  for ( itE = m_entries.begin(); m_entries.end() != itE; ++itE ) {
94  Algorithm* myAlg = itE->algorithm();
95  if ( ! myAlg->isEnabled() ) continue;
96  if ( ! myAlg->isExecuted() ) {
97  if ( m_measureTime ) m_timerTool->start( itE->timer() );
98  result = myAlg->sysExecute();
99  if ( m_measureTime ) m_timerTool->stop( itE->timer() );
100  myAlg->setExecuted( true );
101  if ( ! result.isSuccess() ) break; //== Abort and return bad status
102  }
103  //== Check the returned status
104  if ( !m_ignoreFilter ) {
105  bool passed = myAlg->filterPassed();
106  if (msgLevel(MSG::VERBOSE))
107  verbose() << "Algorithm " << myAlg->name() << " returned filter passed "
108  << (passed ? "true" : "false") << endmsg;
109  if ( itE->reverse() ) passed = !passed;
110 
111 
112  //== indicate our own result. For OR, exit as soon as true.
113  // If no more, will exit with false.
114  //== for AND, exit as soon as false. Else, will be true (default)
115 
116  // if not short-circuiting, make sure we latch iPass to 'true' in
117  // OR mode (i.e. it is sufficient for one item to be true in order
118  // to be true at the end, and thus we start out at 'false'), and latch
119  // to 'false' in AND mode (i.e. it is sufficient for one item to
120  // be false to the false in the end, and thus we start out at 'true')
121  // -- i.e. we should not just blindly return the 'last' passed status!
122 
123  // or to put it another way: in OR mode, we don't care about things
124  // which are false, as they leave our current state alone (provided
125  // we stared as 'false'!), and in AND mode, we keep our current
126  // state until someone returns 'false' (provided we started as 'true')
127  if ( m_modeOR ? passed : !passed ) {
128  seqPass = passed;
129  if (msgLevel(MSG::VERBOSE))
130  verbose() << "SeqPass is now " << (seqPass ? "true" : "false") << endmsg;
131  if (m_shortCircuit) break;
132  }
133  }
134 
135  }
136  if (msgLevel(MSG::VERBOSE))
137  verbose() << "SeqPass is " << (seqPass ? "true" : "false") << endmsg;
138  if ( !m_ignoreFilter && !m_entries.empty() ) setFilterPassed( seqPass );
139  setExecuted( true );
140 
142 
143  return m_returnOK ? StatusCode::SUCCESS : result;
144 }
145 
146 //=============================================================================
147 // Finalize
148 //=============================================================================
150 
151  if (msgLevel(MSG::DEBUG)) debug() << "==> Finalize" << endmsg;
152  return GaudiAlgorithm::finalize();
153 }
154 
155 //=========================================================================
156 // Execute the beginRun of every algorithm
157 //=========================================================================
159 
160  if ( !isEnabled() ) return StatusCode::SUCCESS;
161 
162  if (msgLevel(MSG::DEBUG)) debug() << "==> beginRun" << endmsg;
163  return StatusCode::SUCCESS;
164 }
165 
166 //=========================================================================
167 // Execute the endRun() of every algorithm
168 //=========================================================================
170 
171  if ( !isEnabled() ) return StatusCode::SUCCESS;
172 
173  if (msgLevel(MSG::DEBUG)) debug() << "==> endRun" << endmsg;
174  return StatusCode::SUCCESS;
175 }
176 
177 //=========================================================================
178 // reset the executed status of all members
179 //=========================================================================
182  // algorithm doesn't call resetExecuted of subalgos! should it???
183  std::vector<AlgorithmEntry>::const_iterator itE;
184  for ( itE = m_entries.begin(); m_entries.end() != itE; ++itE ) {
185  itE->algorithm()->resetExecuted();
186  }
187 }
188 //=========================================================================
189 // Decode the input names and fills the m_algs vector.
190 //=========================================================================
191 #ifdef __ICC
192 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
193 // The comparison are meant
194 #pragma warning(push)
195 #pragma warning(disable:1572)
196 #endif
198 
200  m_entries.clear();
201 
202  //== Get the "Context" option if in the file...
203  IJobOptionsSvc* jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
204  bool addedContext = false; //= Have we added the context ?
205  bool addedRootInTES = false; //= Have we added the rootInTES ?
206  bool addedGlobalTimeOffset = false; //= Have we added the globalTimeOffset ?
207 
208 
209  //= Get the Application manager, to see if algorithm exist
210  IAlgManager* appMgr = svc<IAlgManager>("ApplicationMgr");
211  const std::vector<std::string>& nameVector = m_names.value();
212  std::vector<std::string>::const_iterator it;
213  for ( it = nameVector.begin(); nameVector.end() != it; it++ ) {
214  const Gaudi::Utils::TypeNameString typeName(*it);
215  const std::string &theName = typeName.name();
216  const std::string &theType = typeName.type();
217 
218  //== Check wether the specified algorithm already exists. If not, create it
220  SmartIF<IAlgorithm> myIAlg = appMgr->algorithm(typeName, false); // do not create it now
221  if ( !myIAlg.isValid() ) {
222  //== Set the Context if not in the jobOptions list
223  if ( "" != context() ||
224  "" != rootInTES() ||
225  0.0 != globalTimeOffset() ) {
226  bool foundContext = false;
227  bool foundRootInTES = false;
228  bool foundGlobalTimeOffset = false;
229  const std::vector<const Property*>* properties = jos->getProperties( theName );
230  if ( 0 != properties ) {
231  // Iterate over the list to set the options
232  for ( std::vector<const Property*>::const_iterator itProp = properties->begin();
233  itProp != properties->end();
234  itProp++ ) {
235  const StringProperty* sp = dynamic_cast<const StringProperty*>(*itProp);
236  if ( 0 != sp ) {
237  if ( "Context" == (*itProp)->name() ) {
238  foundContext = true;
239  }
240  if ( "RootInTES" == (*itProp)->name() ) {
241  foundRootInTES = true;
242  }
243  if ( "GlobalTimeOffset" == (*itProp)->name() ) {
244  foundGlobalTimeOffset = true;
245  }
246  }
247  }
248  }
249  if ( !foundContext && "" != context() ) {
250  StringProperty contextProperty( "Context", context() );
251  jos->addPropertyToCatalogue( theName, contextProperty ).ignore();
252  addedContext = true;
253  }
254  if ( !foundRootInTES && "" != rootInTES() ) {
255  StringProperty rootInTESProperty( "RootInTES", rootInTES() );
256  jos->addPropertyToCatalogue( theName, rootInTESProperty ).ignore();
257  addedRootInTES = true;
258  }
259  if ( !foundGlobalTimeOffset && 0.0 != globalTimeOffset() ) {
260  DoubleProperty globalTimeOffsetProperty( "GlobalTimeOffset", globalTimeOffset() );
261  jos->addPropertyToCatalogue( theName, globalTimeOffsetProperty ).ignore();
262  addedGlobalTimeOffset = true;
263  }
264  }
265 
266  Algorithm *myAlg = 0;
267  result = createSubAlgorithm( theType, theName, myAlg );
268  // (MCl) this should prevent bug #35199... even if I didn't manage to
269  // reproduce it with a simple test.
270  if (result.isSuccess()) myIAlg = myAlg;
271  } else {
272  Algorithm *myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
273  if (myAlg) {
274  subAlgorithms()->push_back(myAlg);
275  // when the algorithm is not created, the ref count is short by one, so we have to fix it.
276  myAlg->addRef();
277  }
278  }
279 
280  //== Remove the property, in case this is not a GaudiAlgorithm...
281  if ( addedContext ) {
282  jos->removePropertyFromCatalogue( theName, "Context" ).ignore();
283  addedContext = false;
284  }
285  if ( addedRootInTES ) {
286  jos->removePropertyFromCatalogue( theName, "RootInTES" ).ignore();
287  addedRootInTES = false;
288  }
289  if ( addedGlobalTimeOffset ) {
290  jos->removePropertyFromCatalogue( theName, "GlobalTimeOffset" ).ignore();
291  addedGlobalTimeOffset = false;
292  }
293 
294  // propagate the sub-algorithm into own state.
295  if ( result.isSuccess () &&
297  myIAlg.isValid () &&
298  Gaudi::StateMachine::INITIALIZED > myIAlg->FSMState() )
299  {
300  StatusCode sc = myIAlg->sysInitialize() ;
301  if ( sc.isFailure() ) { result = sc ; }
302  }
303 
304  // propagate the sub-algorithm into own state.
305  if ( result.isSuccess () &&
307  myIAlg.isValid () &&
308  Gaudi::StateMachine::RUNNING > myIAlg->FSMState() )
309  {
310  StatusCode sc = myIAlg->sysStart () ;
311  if ( sc.isFailure() ) { result = sc ; }
312  }
313 
314  //== Is it an Algorithm ? Strange test...
315  if ( result.isSuccess() ) {
316  // TODO: (MCl) it is possible to avoid the dynamic_cast in most of the
317  // cases by keeping the result of createSubAlgorithm.
318  Algorithm* myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
319  if (myAlg!=0) {
320  // Note: The reference counting is kept by the system of sub-algorithms
321  m_entries.push_back( AlgorithmEntry( myAlg ) );
322  if (msgLevel(MSG::DEBUG)) debug () << "Added algorithm " << theName << endmsg;
323  } else {
324  warning() << theName << " is not an Algorithm - failed dynamic_cast"
325  << endmsg;
326  final = StatusCode::FAILURE;
327  }
328  } else {
329  warning() << "Unable to find or create " << theName << endmsg;
330  final = result;
331  }
332 
333  }
334 
335  release(appMgr).ignore();
336  release(jos).ignore();
337 
338  //== Print the list of algorithms
339  MsgStream& msg = info();
340  if ( m_modeOR ) msg << "OR ";
341  msg << "Member list: ";
342  std::vector<AlgorithmEntry>::iterator itE;
343  for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
344  Algorithm* myAlg = (*itE).algorithm();
345  std::string myAlgType = System::typeinfoName( typeid( *myAlg) ) ;
346  if ( myAlg->name() == myAlgType ) {
347  msg << myAlg->name();
348  } else {
349  msg << myAlgType << "/" << myAlg->name();
350  }
351  if ( itE+1 != m_entries.end() ) msg << ", ";
352  }
353  if ( "" != context() ) msg << ", with context '" << context() << "'";
354  if ( "" != rootInTES() ) msg << ", with rootInTES '" << rootInTES() << "'";
355  if ( 0.0 != globalTimeOffset() ) msg << ", with globalTimeOffset " << globalTimeOffset();
356  msg << endmsg;
357 
358  return final;
359 
360 }
361 #ifdef __ICC
362 // re-enable icc remark #1572
363 #pragma warning(pop)
364 #endif
365 
366 //=========================================================================
367 // Interface for the Property manager
368 //=========================================================================
370 {
371  // no action for not-yet initialized sequencer
372  if ( Gaudi::StateMachine::INITIALIZED > FSMState() ) { return ; } // RETURN
373 
374  decodeNames().ignore();
375 
376  if ( !m_measureTime ) { return ; } // RETURN
377 
378  // add the entries into timer table:
379 
380  if ( 0 == m_timerTool )
381  { m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" ) ; }
382 
383  if ( m_timerTool->globalTiming() ) m_measureTime = true;
384 
387 
388  for ( std::vector<AlgorithmEntry>::iterator itE = m_entries.begin() ;
389  m_entries.end() != itE; ++itE )
390  {
391  itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
392  }
393 
395 
396 }
397 //=============================================================================

Generated at Wed Jun 4 2014 14:48:55 for Gaudi Framework, version v25r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004