GaudiSequencer.cpp
Go to the documentation of this file.
1 // Include files
2 
3 // from Gaudi
4 #include "GaudiKernel/IAlgManager.h"
5 #include "GaudiAlg/GaudiSequencer.h"
6 #include "GaudiAlg/ISequencerTimerTool.h"
7 #include "GaudiKernel/IJobOptionsSvc.h"
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 // Decode the input names and fills the m_algs vector.
179 //=========================================================================
180 #ifdef __ICC
181 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
182 // The comparison are meant
183 #pragma warning(push)
184 #pragma warning(disable:1572)
185 #endif
187 
189  m_entries.clear();
190 
191  //== Get the "Context" option if in the file...
192  IJobOptionsSvc* jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
193  bool addedContext = false; //= Have we added the context ?
194  bool addedRootInTES = false; //= Have we added the rootInTES ?
195  bool addedGlobalTimeOffset = false; //= Have we added the globalTimeOffset ?
196 
197 
198  //= Get the Application manager, to see if algorithm exist
199  IAlgManager* appMgr = svc<IAlgManager>("ApplicationMgr");
200  const std::vector<std::string>& nameVector = m_names.value();
201  std::vector<std::string>::const_iterator it;
202  for ( it = nameVector.begin(); nameVector.end() != it; it++ ) {
204  const std::string &theName = typeName.name();
205  const std::string &theType = typeName.type();
206 
207  //== Check wether the specified algorithm already exists. If not, create it
209  SmartIF<IAlgorithm> myIAlg = appMgr->algorithm(typeName, false); // do not create it now
210  if ( !myIAlg.isValid() ) {
211  //== Set the Context if not in the jobOptions list
212  if ( "" != context() ||
213  "" != rootInTES() ||
214  0.0 != globalTimeOffset() ) {
215  bool foundContext = false;
216  bool foundRootInTES = false;
217  bool foundGlobalTimeOffset = false;
218  const std::vector<const Property*>* properties = jos->getProperties( theName );
219  if ( 0 != properties ) {
220  // Iterate over the list to set the options
221  for ( std::vector<const Property*>::const_iterator itProp = properties->begin();
222  itProp != properties->end();
223  itProp++ ) {
224  const StringProperty* sp = dynamic_cast<const StringProperty*>(*itProp);
225  if ( 0 != sp ) {
226  if ( "Context" == (*itProp)->name() ) {
227  foundContext = true;
228  }
229  if ( "RootInTES" == (*itProp)->name() ) {
230  foundRootInTES = true;
231  }
232  if ( "GlobalTimeOffset" == (*itProp)->name() ) {
233  foundGlobalTimeOffset = true;
234  }
235  }
236  }
237  }
238  if ( !foundContext && "" != context() ) {
239  StringProperty contextProperty( "Context", context() );
240  jos->addPropertyToCatalogue( theName, contextProperty ).ignore();
241  addedContext = true;
242  }
243  if ( !foundRootInTES && "" != rootInTES() ) {
244  StringProperty rootInTESProperty( "RootInTES", rootInTES() );
245  jos->addPropertyToCatalogue( theName, rootInTESProperty ).ignore();
246  addedRootInTES = true;
247  }
248  if ( !foundGlobalTimeOffset && 0.0 != globalTimeOffset() ) {
249  DoubleProperty globalTimeOffsetProperty( "GlobalTimeOffset", globalTimeOffset() );
250  jos->addPropertyToCatalogue( theName, globalTimeOffsetProperty ).ignore();
251  addedGlobalTimeOffset = true;
252  }
253  }
254 
255  Algorithm *myAlg = 0;
256  result = createSubAlgorithm( theType, theName, myAlg );
257  // (MCl) this should prevent bug #35199... even if I didn't manage to
258  // reproduce it with a simple test.
259  if (result.isSuccess()) myIAlg = myAlg;
260  } else {
261  Algorithm *myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
262  if (myAlg) {
263  subAlgorithms()->push_back(myAlg);
264  // when the algorithm is not created, the ref count is short by one, so we have to fix it.
265  myAlg->addRef();
266  }
267  }
268 
269  //== Remove the property, in case this is not a GaudiAlgorithm...
270  if ( addedContext ) {
271  jos->removePropertyFromCatalogue( theName, "Context" ).ignore();
272  addedContext = false;
273  }
274  if ( addedRootInTES ) {
275  jos->removePropertyFromCatalogue( theName, "RootInTES" ).ignore();
276  addedRootInTES = false;
277  }
278  if ( addedGlobalTimeOffset ) {
279  jos->removePropertyFromCatalogue( theName, "GlobalTimeOffset" ).ignore();
280  addedGlobalTimeOffset = false;
281  }
282 
283  // propagate the sub-algorithm into own state.
284  if ( result.isSuccess () &&
286  myIAlg.isValid () &&
288  {
289  StatusCode sc = myIAlg->sysInitialize() ;
290  if ( sc.isFailure() ) { result = sc ; }
291  }
292 
293  // propagate the sub-algorithm into own state.
294  if ( result.isSuccess () &&
296  myIAlg.isValid () &&
298  {
299  StatusCode sc = myIAlg->sysStart () ;
300  if ( sc.isFailure() ) { result = sc ; }
301  }
302 
303  //== Is it an Algorithm ? Strange test...
304  if ( result.isSuccess() ) {
305  // TODO: (MCl) it is possible to avoid the dynamic_cast in most of the
306  // cases by keeping the result of createSubAlgorithm.
307  Algorithm* myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
308  if (myAlg!=0) {
309  // Note: The reference counting is kept by the system of sub-algorithms
310  m_entries.push_back( AlgorithmEntry( myAlg ) );
311  if (msgLevel(MSG::DEBUG)) debug () << "Added algorithm " << theName << endmsg;
312  } else {
313  warning() << theName << " is not an Algorithm - failed dynamic_cast"
314  << endmsg;
315  final = StatusCode::FAILURE;
316  }
317  } else {
318  warning() << "Unable to find or create " << theName << endmsg;
319  final = result;
320  }
321 
322  }
323 
324  release(appMgr).ignore();
325  release(jos).ignore();
326 
327  //== Print the list of algorithms
328  MsgStream& msg = info();
329  if ( m_modeOR ) msg << "OR ";
330  msg << "Member list: ";
331  std::vector<AlgorithmEntry>::iterator itE;
332  for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
333  Algorithm* myAlg = (*itE).algorithm();
334  std::string myAlgType = System::typeinfoName( typeid( *myAlg) ) ;
335  if ( myAlg->name() == myAlgType ) {
336  msg << myAlg->name();
337  } else {
338  msg << myAlgType << "/" << myAlg->name();
339  }
340  if ( itE+1 != m_entries.end() ) msg << ", ";
341  }
342  if ( "" != context() ) msg << ", with context '" << context() << "'";
343  if ( "" != rootInTES() ) msg << ", with rootInTES '" << rootInTES() << "'";
344  if ( 0.0 != globalTimeOffset() ) msg << ", with globalTimeOffset " << globalTimeOffset();
345  msg << endmsg;
346 
347  return final;
348 
349 }
350 #ifdef __ICC
351 // re-enable icc remark #1572
352 #pragma warning(pop)
353 #endif
354 
355 //=========================================================================
356 // Interface for the Property manager
357 //=========================================================================
359 {
360  // no action for not-yet initialized sequencer
361  if ( Gaudi::StateMachine::INITIALIZED > FSMState() ) { return ; } // RETURN
362 
363  decodeNames().ignore();
364 
365  if ( !m_measureTime ) { return ; } // RETURN
366 
367  // add the entries into timer table:
368 
369  if ( 0 == m_timerTool )
370  { m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" ) ; }
371 
372  if ( m_timerTool->globalTiming() ) m_measureTime = true;
373 
376 
377  for ( std::vector<AlgorithmEntry>::iterator itE = m_entries.begin() ;
378  m_entries.end() != itE; ++itE )
379  {
380  itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
381  }
382 
384 
385 }
386 //=============================================================================
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
virtual StatusCode sysStart()=0
Startup method invoked by the framework.
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.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
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:75
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:299
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:402
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:85
virtual bool globalTiming()=0
returns the flag telling that global timing is wanted
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
MSG::Level msgLevel() const
The current message service output level.
Definition: GaudiCommon.h:532
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:62
virtual void declareUpdateHandler(PropertyCallbackFunctor *pf)
set new callback for update
Definition: Property.cpp:141
virtual StatusCode finalize()
standard finalization method
Helper class to parse a string of format "type/name".
Definition: TypeNameString.h:9
Main interface for the JobOptions service.
virtual Gaudi::StateMachine::State FSMState() const =0
Get the current state.
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
const TYPE & value() const
explicit conversion
Definition: Property.h:355
virtual StatusCode beginRun()
Algorithm beginRun.
StatusCode decodeNames()
Decode a vector of string.
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
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:51
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:107
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.
std::vector< AlgorithmEntry > m_entries
List of algorithms to process.
int m_timer
Timer number for the sequencer.
ISequencerTimerTool * m_timerTool
Pointer to the timer tool.
StringArrayProperty m_names
Input string, list of algorithms.