Gaudi Framework, version v23r6

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

Generated at Wed Jan 30 2013 17:13:37 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004