ATLAS Offline Software
AthSequencer.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // AthSequencer.cxx
8 // Implementation file for class AthSequencer
9 // Author: S.Binet<binet@cern.ch>
11 
12 // AthSequencer class
13 // Implements:
14 // 1) Common functionality of IInterface
15 // 2) Default behaviour for the IAlgorithm
16 
17 #include "AthSequencer.h"
18 
19 #include "GaudiKernel/IAlgManager.h"
20 #include "GaudiKernel/ISvcLocator.h"
22 
23 
27 AthSequencer::AthSequencer( const std::string& name,
28  ISvcLocator* pSvcLocator ):
29  ::AthCommonDataStore<AthCommonMsg<Gaudi::Sequence>> ( name, pSvcLocator ),
30  m_clidSvc("ClassIDSvc/ClassIDSvc", name)
31 {
32  m_names.declareUpdateHandler( &AthSequencer::membershipHandler, this );
33 }
34 
39 {}
40 
43 {
44  if (!decodeMemberNames().isSuccess()) {
45  ATH_MSG_ERROR ("Unable to configure one or more sequencer members ");
46  return StatusCode::FAILURE;
47  }
48 
49  Ath::DynamicDataHelper dynamic_data_helper;
50  StatusCode sc(StatusCode::SUCCESS);
51  // Loop over all sub-algorithms
52  for (Gaudi::Algorithm* theAlgorithm : *subAlgorithms()) {
53  if (!theAlgorithm->sysInitialize( ).isSuccess()) {
54  ATH_MSG_ERROR ("Unable to initialize Algorithm "
55  << theAlgorithm->type() << "/" << theAlgorithm->name());
56  sc= StatusCode::FAILURE;
57  }
58  else if (m_runPostInitialize) {
59  // visit all algorithms and its tools to gather their input, output handles and dynamic data consumers
60  dynamic_data_helper.gatherDataHandlesAndDynamicConsumers(this->name(),theAlgorithm);
61  }
62  }
63  if (sc.isSuccess() && m_runPostInitialize) {
64  ATH_MSG_DEBUG("Allow dynamic data consumers to update their data dependencies.");
65  if (!m_undeclaredOutputData.empty()) {
66  ATH_CHECK( m_clidSvc.retrieve() );
67  ATH_CHECK( dynamic_data_helper.addExtraDependencies(*m_clidSvc, m_undeclaredOutputData.value(), msg() ) );
68  }
69  dynamic_data_helper.updateDataNeeds(m_maxPass, msg());
70  }
71  return sc;
72 }
73 
76 {
77  StatusCode sc(StatusCode::SUCCESS);
78  // Bypass the loop if this sequencer is disabled
79  if ( isEnabled( ) ) {
80 
81  // Loop over all members calling their reinitialize functions
82  // if they are not disabled.
83  for (Gaudi::Algorithm* theAlgorithm : *subAlgorithms()) {
84  if ( theAlgorithm->isEnabled( ) ) {
85  if (theAlgorithm->sysReinitialize( ).isFailure()) {
86  ATH_MSG_ERROR ("Unable to reinitialize Algorithm "
87  << theAlgorithm->type () << "/"
88  << theAlgorithm->name());
89  sc = StatusCode::FAILURE;
90  }
91  }
92  }
93  }
94  return sc;
95 }
96 
98 AthSequencer::execute( const EventContext& ctx ) const
99 {
100  StatusCode sc = StatusCode::SUCCESS;
101  bool seqPass = !m_modeOR;
102 
103  ATH_MSG_DEBUG ("Executing " << name() << "...");
104 
105  auto state = execState( ctx );
106 
107  // Bypass the loop if this sequencer is disabled or has already been executed
108  if ( isEnabled( ) && state.state() != AlgExecState::State::Done ) {
109 
110  // Prevent multiple executions of this sequencer for the current event
111  state.setState( AlgExecState::State::Executing );
112 
113  // Loop over all algorithms calling their execute functions if they
114  // are (a) not disabled, and (b) aren't already executed. Note that
115  // in the latter case the filter state is still examined. Terminate
116  // the loop if an algorithm indicates that it's filter didn't pass.
117  const std::vector<Gaudi::Algorithm*>* subAlgms = subAlgorithms( );
118  for (auto theAlgorithm : *subAlgms) {
119  if ( theAlgorithm->isEnabled( ) ) {
120  if ( theAlgorithm->execState(ctx).state() == AlgExecState::State::None ) {
121  sc = executeAlgorithm (theAlgorithm, ctx);
122  }
123 
124  if ( sc.isSuccess() ) {
125 
126  if ( !m_ignoreFilter ) {
127  // Take the filter passed status of this algorithm as my own status
128  const bool passed = theAlgorithm->execState( ctx ).filterPassed();
129  if ( m_invert ) {
130  state.setFilterPassed( !passed );
131  } else {
132  state.setFilterPassed( passed );
133  }
134 
135  // The behaviour when the filter fails depends on the
136  // StopOverride property.
137  // The default action is to stop processing, but this default can be
138  // overridden by setting the "StopOverride" property to false.
139  if ( m_modeOR ? passed : !passed ) {
140  seqPass = passed;
141  if ( !m_stopOverride ) break;
142  }
143  }
144  } else {
145  ATH_MSG_INFO ("execute of [" << theAlgorithm->name() << "] did NOT succeed");
146  break;
147  }
148  }
149  }
150  }
151 
152  if ( !m_ignoreFilter && !m_names.empty() ) {
153  if ( m_invert ) {
154  state.setFilterPassed( !seqPass );
155  } else {
156  state.setFilterPassed( seqPass );
157  }
158  }
159 
160  state.setState( AlgExecState::State::Done );
161 
162  return sc;
163 }
164 
165 
166 StatusCode AthSequencer::executeAlgorithm (Gaudi::Algorithm* theAlgorithm,
167  const EventContext& ctx) const
168 {
169  // Call the sysExecute() of the method the algorithm
170  return theAlgorithm->sysExecute( ctx );
171 }
172 
175 {
176  StatusCode sc(StatusCode::SUCCESS);
177  // Loop over all sub-algorithms
178  for (Gaudi::Algorithm* theAlgorithm : *subAlgorithms()) {
179  if (!theAlgorithm->sysStart( ).isSuccess()) {
180  ATH_MSG_ERROR ("Unable to start Algorithm "
181  << theAlgorithm->type () << "/"
182  << theAlgorithm->name());
183  sc = StatusCode::FAILURE;
184  }
185  }
186  return sc;
187 }
188 
191 {
192  StatusCode sc(StatusCode::SUCCESS);
193  // Loop over all sub-algorithms if they are not disabled.
194  for (Gaudi::Algorithm* theAlgorithm : *subAlgorithms()) {
195  if (theAlgorithm->sysStop( ).isFailure()) {
196  ATH_MSG_ERROR ("Unable to stop Algorithm "
197  << theAlgorithm->type () << "/"
198  << theAlgorithm->name());
199  sc = StatusCode::FAILURE;
200  }
201  }
202  return sc;
203 }
204 
205 void
206 AthSequencer::resetExecuted( const EventContext& ctx ) const
207 {
208  execState(ctx).reset();
209 
210  // Loop over all members calling their resetExecuted functions
211  // if they are not disabled.
212  for (Gaudi::Algorithm* theAlgorithm : *subAlgorithms()) {
213  theAlgorithm->execState(ctx).reset();
214  }
215 }
216 
217 bool
219 {
220  return m_stopOverride.value( );
221 }
222 
224 AthSequencer::append( Gaudi::Algorithm* pAlgorithm )
225 {
226  return append( pAlgorithm, subAlgorithms( ) );
227 }
228 
231  const std::string& name,
232  Gaudi::Algorithm*& pAlgorithm )
233 {
234  return createAndAppend( type, name, pAlgorithm, subAlgorithms( ) );
235 }
236 
238 AthSequencer::remove( Gaudi::Algorithm* pAlgorithm )
239 {
240  return remove (pAlgorithm->name());
241 }
242 
244 AthSequencer::remove( const std::string& algname )
245 {
246  return remove( algname, subAlgorithms( ) );
247 }
248 
251 {
252  // Decode the membership list
253  return decodeNames( m_names, subAlgorithms() );
254 }
255 
256 void
257 AthSequencer::membershipHandler( Gaudi::Details::PropertyBase& /* theProp */ )
258 {
259  if ( isInitialized() ) decodeMemberNames().ignore();
260 }
261 
267 AthSequencer::append( Gaudi::Algorithm* pAlgorithm,
268  std::vector<Gaudi::Algorithm*>* theAlgs )
269 {
270  bool all_good = true;
271  // Check that the specified algorithm doesn't already exist
272  // in the membership list
273  for (Gaudi::Algorithm* theAlgorithm : *theAlgs) {
274  if ( theAlgorithm == pAlgorithm ) {
275  all_good = false;
276  break;
277  }
278  }
279  if ( all_good ) {
280  theAlgs->push_back( pAlgorithm );
281  pAlgorithm->addRef();
282  }
283  return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
284 }
285 
286 StatusCode
288  const std::string& algName,
289  Gaudi::Algorithm*& pAlgorithm,
290  std::vector<Gaudi::Algorithm*>* theAlgs )
291 {
292  SmartIF<IAlgManager> theAlgMgr(Gaudi::svcLocator()->as<IAlgManager>());
293  IAlgorithm* tmp = nullptr;
294 
295  ATH_CHECK( theAlgMgr->createAlgorithm( type, algName, tmp ) );
296  pAlgorithm = dynamic_cast<Gaudi::Algorithm*>(tmp);
297  theAlgs->push_back( pAlgorithm );
298 
299  return StatusCode::SUCCESS;
300 }
301 
303 AthSequencer::decodeNames( Gaudi::Property<std::vector<std::string>>& theNames,
304  std::vector<Gaudi::Algorithm*>* theAlgs )
305 {
306  SmartIF<IAlgManager> theAlgMgr(Gaudi::svcLocator()->as<IAlgManager>());
307 
308  // Clear the existing list of algorithms
309  theAlgs->clear( );
310 
311  // Build the list of member algorithms from the contents of the
312  // theNames list.
313  StatusCode result = StatusCode::SUCCESS;
314  for (const std::string& name : theNames.value()) {
315 
316  // Parse the name for a syntax of the form <type>/<name>
317  Gaudi::Utils::TypeNameString tn(name);
318 
319  // Check whether the supplied name corresponds to an existing
320  // Algorithm object.
321  SmartIF<IAlgorithm>& theIAlg = theAlgMgr->algorithm(tn.name(), /*createIf*/false);
322  Gaudi::Algorithm* theAlgorithm = nullptr;
323  if ( theIAlg ) {
324  theAlgorithm = dynamic_cast<Gaudi::Algorithm*>(theIAlg.get());
325  if ( theAlgorithm ) {
326  // The specified Algorithm already exists -
327  // just append it to the membership list.
328  if ( append(theAlgorithm, theAlgs).isSuccess( ) ) {
329  ATH_MSG_DEBUG (tn.name() << " already exists - appended to member list");
330  } else {
331  ATH_MSG_WARNING (tn.name() << " already exists - append failed!!!");
332  result = StatusCode::FAILURE;
333  }
334  }
335  else {
336  ATH_MSG_WARNING (tn.name() << " is not an Algorithm - Failed dynamic cast");
337  result = StatusCode::FAILURE;
338  }
339  } else {
340  // The specified name doesn't exist -
341  // create a new object of the specified type and append it to
342  // the membership list.
343  if ( createAndAppend(tn.type(), tn.name(), theAlgorithm, theAlgs).isSuccess( ) ) {
344  ATH_MSG_DEBUG (tn.name() << " doesn't exist - created and appended to member list");
345  } else {
346  ATH_MSG_WARNING (tn.name() << " doesn't exist - creation failed!!!");
347  result = StatusCode::FAILURE;
348  }
349  }
350  } //> loop over names
351 
352  // Print membership list
353  if (msgLvl(MSG::DEBUG)) {
354  if ( result.isSuccess() && !theAlgs->empty() ) {
355 
356  msg(MSG::DEBUG) << "Member list: ";
357  bool first = true;
358  for (Gaudi::Algorithm* alg : *theAlgs) {
359  if (first)
360  first = false;
361  else
362  msg() << ", ";
363  if ( alg->name() == System::typeinfoName(typeid(*alg)))
364  msg() << alg->name();
365  else
366  msg() << System::typeinfoName(typeid(*alg)) << "/" << alg->name();
367  }
368  msg(MSG::DEBUG) << endmsg;
369  }
370  }
371  return result;
372 }
373 
375 AthSequencer::remove( const std::string& /*algname*/,
376  std::vector<Gaudi::Algorithm*>* /*theAlgs*/ )
377 {
378  ATH_MSG_ERROR ("AthSequencer::remove( ) is not supported");
379  return StatusCode::FAILURE;
380 }
python.samplers.Sequence
Sequence
Alias:
Definition: samplers.py:237
AthSequencer::append
StatusCode append(Gaudi::Algorithm *pAlgorithm)
Append an algorithm to the sequencer.
Definition: AthSequencer.cxx:224
AthSequencer::~AthSequencer
virtual ~AthSequencer()
Destructor.
Definition: AthSequencer.cxx:38
AthSequencer::AthSequencer
AthSequencer(const std::string &name, ISvcLocator *svcloc)
Constructor(s)
Definition: AthSequencer.cxx:27
getMenu.algname
algname
Definition: getMenu.py:54
AthSequencer::m_clidSvc
ServiceHandle< IClassIDSvc > m_clidSvc
Definition: AthSequencer.h:203
get_generator_info.result
result
Definition: get_generator_info.py:21
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:118
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Ath::DynamicDataHelper
Helper class to gather all declared data IDs and propagate them to components which declare data depe...
Definition: DynamicDataHelper.h:25
AthSequencer::decodeMemberNames
StatusCode decodeMemberNames()
Decode Member Name list.
Definition: AthSequencer.cxx:250
xAOD::JetAlgorithmType::algName
const std::string & algName(ID id)
Converts a JetAlgorithmType::ID into a string.
Definition: JetContainerInfo.cxx:67
AthCommonMsg< Gaudi::Sequence >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
AthSequencer::m_invert
Gaudi::Property< bool > m_invert
Definition: AthSequencer.h:187
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
AthSequencer::m_maxPass
const unsigned int m_maxPass
Definition: AthSequencer.h:205
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthSequencer::initialize
virtual StatusCode initialize() override
Initialization of a sequencer.
Definition: AthSequencer.cxx:42
AthSequencer::m_modeOR
Gaudi::Property< bool > m_modeOR
Definition: AthSequencer.h:181
AthSequencer::m_runPostInitialize
Gaudi::Property< bool > m_runPostInitialize
Definition: AthSequencer.h:199
CaloCellPos2Ntuple.None
None
Definition: CaloCellPos2Ntuple.py:23
AthSequencer::m_undeclaredOutputData
Gaudi::Property< std::vector< std::string > > m_undeclaredOutputData
Definition: AthSequencer.h:196
AthCommonDataStore
Definition: AthCommonDataStore.h:52
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Athena::typeinfoName
std::string typeinfoName(const std::type_info &ti)
Convert a type_info to a demangled string.
Definition: AthenaKernel/src/ClassName.cxx:23
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthSequencer::m_ignoreFilter
Gaudi::Property< bool > m_ignoreFilter
Definition: AthSequencer.h:184
AthSequencer::resetExecuted
virtual void resetExecuted(const EventContext &ctx) const
Reset the AthSequencer executed state for the current event.
Definition: AthSequencer.cxx:206
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
AthSequencer::execute
virtual StatusCode execute(const EventContext &ctx) const override
The actions to be performed by the sequencer on an event.
Definition: AthSequencer.cxx:98
AthSequencer::membershipHandler
void membershipHandler(Gaudi::Details::PropertyBase &theProp)
"Members" property handler
Definition: AthSequencer.cxx:257
AthSequencer::isStopOverride
virtual bool isStopOverride() const
Has the StopOverride mode been set?
Definition: AthSequencer.cxx:218
Ath::DynamicDataHelper::gatherDataHandlesAndDynamicConsumers
void gatherDataHandlesAndDynamicConsumers(const std::string &parent_name, Gaudi::Algorithm *theAlgorithm)
Gather the input and output data declared by the given algorithm, its child algorithms and their tool...
Definition: DynamicDataHelper.cxx:65
AthSequencer::remove
StatusCode remove(Gaudi::Algorithm *pAlgorithm)
Remove the specified algorithm from the sequencer.
Definition: AthSequencer.cxx:238
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
AthSequencer::m_names
Gaudi::Property< std::vector< std::string > > m_names
Definition: AthSequencer.h:178
RegSelToolConfig.alg
alg
Definition: RegSelToolConfig.py:332
AthSequencer::start
virtual StatusCode start() override
Start (from INITIALIZED to RUNNING).
Definition: AthSequencer.cxx:174
AthSequencer::executeAlgorithm
StatusCode executeAlgorithm(Gaudi::Algorithm *theAlgorithm, const EventContext &ctx) const
Run one algorithm.
Definition: AthSequencer.cxx:166
AthSequencer::createAndAppend
StatusCode createAndAppend(const std::string &type, const std::string &name, Gaudi::Algorithm *&pAlgorithm)
Create a algorithm and append it to the sequencer.
Definition: AthSequencer.cxx:230
AthCommonMsg
Definition: AthCommonMsg.h:19
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AthSequencer::decodeNames
StatusCode decodeNames(Gaudi::Property< std::vector< std::string >> &theNames, std::vector< Gaudi::Algorithm * > *theAlgs)
Decode algorithm names, creating or appending algorithms as appropriate.
Definition: AthSequencer.cxx:303
DeMoScan.first
bool first
Definition: DeMoScan.py:534
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< Gaudi::Sequence >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
AthSequencer::reinitialize
virtual StatusCode reinitialize() override
AthSequencer Reinitialization.
Definition: AthSequencer.cxx:75
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
Ath::DynamicDataHelper::updateDataNeeds
void updateDataNeeds(unsigned int max_pass, MsgStream &out)
Update the data dependencies of all components which dynamically declare tehm.
Definition: DynamicDataHelper.cxx:100
DynamicDataHelper.h
AthSequencer::m_stopOverride
Gaudi::Property< bool > m_stopOverride
Definition: AthSequencer.h:190
Ath::DynamicDataHelper::addExtraDependencies
StatusCode addExtraDependencies(IClassIDSvc &clid_svc, std::vector< std::string > &undeclared_output_data, MsgStream &out)
Add extra output data which is not declared by any of the gathered components.
Definition: DynamicDataHelper.cxx:26
AthSequencer.h
AthSequencer::stop
virtual StatusCode stop() override
Stop (from RUNNING to INITIALIZED).
Definition: AthSequencer.cxx:190