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 ? (result.ignore(), 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++ ) {
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 //=============================================================================
MsgStream & warning() const
shortcut for the method msgStream ( MSG::WARNING )
Definition: GaudiCommon.h:495
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
void membershipHandler(Property &theProp)
for asynchronous changes in the list of algorithms
std::vector< Algorithm * > * subAlgorithms() const
List of sub-algorithms. Returns a pointer to a vector of (sub) Algorithms.
Definition: Algorithm.cpp:870
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
virtual const std::vector< const Property * > * getProperties(const std::string &client) const =0
Get the properties associated to a given client.
bool m_shortCircuit
Indicates whether to stop processing as soon as possible, or to always execute all subalgorithms...
virtual void setExecuted(bool state)
Set the executed flag to the specified state.
Definition: Algorithm.cpp:849
MsgStream & info() const
shortcut for the method msgStream ( MSG::INFO )
Definition: GaudiCommon.h:497
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
virtual void decreaseIndent()=0
Decrease the indentation of the name.
StatusCode createSubAlgorithm(const std::string &type, const std::string &name, Algorithm *&pSubAlg)
Create a sub algorithm.
Definition: Algorithm.cpp:1116
const std::string & rootInTES() const
Returns the "rootInTES" string.
Definition: GaudiCommon.h:758
virtual bool filterPassed() const
Did this algorithm pass or fail its filter criterion for the last event?
Definition: Algorithm.cpp:862
bool m_returnOK
Forces the sequencer to return a good status.
bool m_modeOR
Indicates that the OR is wanted instead of AND.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
virtual int addTimer(const std::string &name)=0
add a timer entry with the specified name
virtual StatusCode sysExecute()
The actions to be performed by the algorithm on an event.
Definition: Algorithm.cpp:578
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:62
StatusCode Error(const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const
Print the error message and return with the given StatusCode.
virtual bool isEnabled() const
Is this algorithm enabled or disabled?
Definition: Algorithm.cpp:858
virtual StatusCode initialize()
standard initialization method
The IAlgManager is the interface implemented by the Algorithm Factory in the Application Manager to s...
Definition: IAlgManager.h:28
virtual bool isExecuted() const
Has this algorithm been executed since the last reset?
Definition: Algorithm.cpp:845
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Algorithm.h:397
const std::string & context() const
Returns the "context" string. Used to identify different processing states.
Definition: GaudiCommon.h:754
virtual void increaseIndent()=0
Increase the indentation of the name.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:72
virtual bool globalTiming()=0
returns the flag telling that global timing is wanted
MSG::Level msgLevel() const
The current message service output level.
Definition: GaudiCommon.h:532
virtual void declareUpdateHandler(PropertyCallbackFunctor *pf)
set new callback for update
Definition: Property.cpp:141
virtual StatusCode finalize()
standard finalization method
ISequencerTimerTool * m_timerTool
Pointer to the timer tool.
Helper class to parse a string of format "type/name".
Definition: TypeNameString.h:9
Main interface for the JobOptions service.
virtual void resetExecuted()
Reset the executed state of the Algorithm for the duration of the current event.
Definition: Algorithm.cpp:853
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:51
virtual unsigned long release()
Un-hide IInterface::release (ICC warning #1125)
Definition: GaudiCommon.h:733
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
virtual void setFilterPassed(bool state)
Set the filter passed flag to the specified state.
Definition: Algorithm.cpp:866
MsgStream & verbose() const
shortcut for the method msgStream ( MSG::VERBOSE )
Definition: GaudiCommon.h:501
virtual StatusCode finalize()
Algorithm finalization.
virtual Gaudi::StateMachine::State FSMState() const
returns the current state of the algorithm
Definition: Algorithm.h:190
bool m_measureTime
Flag to measure time.
virtual StatusCode execute()
Algorithm execution.
virtual const std::string & name() const
The identifying name of the algorithm object.
Definition: Algorithm.cpp:837
The useful base class for data processing algorithms.
MsgStream & msg() const
shortcut for the method msgStream ( MSG::INFO )
Definition: GaudiCommon.h:503
MsgStream & debug() const
shortcut for the method msgStream ( MSG::DEBUG )
Definition: GaudiCommon.h:499
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:62
const TYPE & value() const
explicit conversion
Definition: Property.h:355
virtual StatusCode beginRun()
Algorithm beginRun.
StatusCode decodeNames()
Decode a vector of string.
void resetExecuted()
Called before an event processing.
virtual void start(int index)=0
start the counter, i.e.
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:61
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:43
const std::string & type() const
virtual StatusCode removePropertyFromCatalogue(const std::string &client, const std::string &name)=0
Remove a property from the JobOptions catalog.
virtual ~GaudiSequencer()
Destructor.
virtual StatusCode addPropertyToCatalogue(const std::string &client, const Property &property)=0
Add a property into the JobOptions catalog.
virtual StatusCode initialize()
Algorithm initialization.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
tuple appMgr
Definition: IOTest.py:83
GaudiSequencer(const std::string &name, ISvcLocator *pSvcLocator)
Standard constructor.
const std::string & name() const
double globalTimeOffset() const
Returns the "globalTimeOffset" double.
Definition: GaudiCommon.h:760
void ignore() const
Definition: StatusCode.h:94
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:22
virtual StatusCode endRun()
Algorithm endRun.
virtual double stop(int index)=0
stop the counter, return the elapsed time
bool m_ignoreFilter
True if one continues always.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
int m_timer
Timer number for the sequencer.
std::vector< AlgorithmEntry > m_entries
List of algorithms to process.
StringArrayProperty m_names
Input string, list of algorithms.