ATLAS Offline Software
Loading...
Searching...
No Matches
AthSequencer.cxx
Go to the documentation of this file.
1
2
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
27AthSequencer::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
40
41StatusCode
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
74StatusCode
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
97StatusCode
98AthSequencer::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
166StatusCode 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
173StatusCode
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
189StatusCode
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
205void
206AthSequencer::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
217bool
219{
220 return m_stopOverride.value( );
221}
222
223StatusCode
224AthSequencer::append( Gaudi::Algorithm* pAlgorithm )
225{
226 return append( pAlgorithm, subAlgorithms( ) );
227}
228
229StatusCode
231 const std::string& name,
232 Gaudi::Algorithm*& pAlgorithm )
233{
234 return createAndAppend( type, name, pAlgorithm, subAlgorithms( ) );
235}
236
237StatusCode
238AthSequencer::remove( Gaudi::Algorithm* pAlgorithm )
239{
240 return remove (pAlgorithm->name());
241}
242
243StatusCode
244AthSequencer::remove( const std::string& algname )
245{
246 return remove( algname, subAlgorithms( ) );
247}
248
249StatusCode
251{
252 // Decode the membership list
253 return decodeNames( m_names, subAlgorithms() );
254}
255
256void
257AthSequencer::membershipHandler( Gaudi::Details::PropertyBase& /* theProp */ )
258{
259 if ( isInitialized() ) decodeMemberNames().ignore();
260}
261
265
266StatusCode
267AthSequencer::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
286StatusCode
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
302StatusCode
303AthSequencer::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
374StatusCode
375AthSequencer::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}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool passed(DecisionID id, const DecisionIDContainer &)
checks if required decision ID is in the set of IDs in the container
static Double_t sc
AthCommonDataStore(const std::string &name, T... args)
bool msgLvl(const MSG::Level lvl) const
virtual StatusCode initialize() override
Initialization of a sequencer.
virtual StatusCode reinitialize() override
AthSequencer Reinitialization.
virtual void resetExecuted(const EventContext &ctx) const
Reset the AthSequencer executed state for the current event.
virtual bool isStopOverride() const
Has the StopOverride mode been set?
ServiceHandle< IClassIDSvc > m_clidSvc
virtual StatusCode start() override
Start (from INITIALIZED to RUNNING).
Gaudi::Property< bool > m_invert
StatusCode decodeNames(Gaudi::Property< std::vector< std::string > > &theNames, std::vector< Gaudi::Algorithm * > *theAlgs)
Decode algorithm names, creating or appending algorithms as appropriate.
Gaudi::Property< bool > m_modeOR
StatusCode executeAlgorithm(Gaudi::Algorithm *theAlgorithm, const EventContext &ctx) const
Run one algorithm.
StatusCode remove(Gaudi::Algorithm *pAlgorithm)
Remove the specified algorithm from the sequencer.
virtual StatusCode execute(const EventContext &ctx) const override
The actions to be performed by the sequencer on an event.
void membershipHandler(Gaudi::Details::PropertyBase &theProp)
"Members" property handler
Gaudi::Property< std::vector< std::string > > m_names
virtual ~AthSequencer()
Destructor.
Gaudi::Property< bool > m_ignoreFilter
StatusCode append(Gaudi::Algorithm *pAlgorithm)
Append an algorithm to the sequencer.
Gaudi::Property< bool > m_stopOverride
AthSequencer(const std::string &name, ISvcLocator *svcloc)
Constructor(s)
const unsigned int m_maxPass
virtual StatusCode stop() override
Stop (from RUNNING to INITIALIZED).
StatusCode createAndAppend(const std::string &type, const std::string &name, Gaudi::Algorithm *&pAlgorithm)
Create a algorithm and append it to the sequencer.
StatusCode decodeMemberNames()
Decode Member Name list.
Gaudi::Property< bool > m_runPostInitialize
Gaudi::Property< std::vector< std::string > > m_undeclaredOutputData
Helper class to gather all declared data IDs and propagate them to components which declare data depe...
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.
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...
void updateDataNeeds(unsigned int max_pass, MsgStream &out)
Update the data dependencies of all components which dynamically declare tehm.
=============================================================================