ATLAS Offline Software
Loading...
Searching...
No Matches
DecisionSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "DecisionSvc.h"
6
7// Gaudi include files
8#include "GaudiKernel/EventContext.h"
10#include <algorithm>
11
12DecisionSvc::DecisionSvc(const std::string& name,
13 ISvcLocator* pSvcLocator ) :
14 base_class(name, pSvcLocator),
15 m_evtStore("StoreGateSvc",name),
16#ifdef SIMULATIONBASE
17 m_cutflowSvc("",name),
18#else
19 m_cutflowSvc("CutFlowSvc/CutFlowSvc",name),
20#endif
21 m_algstateSvc("AlgExecStateSvc",name)
22{
23}
24
28
29StatusCode
31{
32 // Decode the accept, required and veto Algorithms.
33 // The logic is the following:
34 // a. The event is accepted if all lists are empty.
35 // b. The event is provisionally accepted if any Algorithm in the
36 // accept list
37 // has been executed and has indicated that its filter is passed. This
38 // provisional acceptance can be overridden by the other lists.
39 // c. The event is rejected unless all Algorithms in the required list have
40 // been executed and have indicated that their filter passed.
41 // d. The event is rejected if any Algorithm in the veto list has been
42 // executed and has indicated that its filter has passed.
43
44 // Set to be listener for BeginRun
45 // Declares top filters to ICutFlowSvc if (and only if) needed (David Cote, Sep 2010)
46
47 // Get handle to exec state service for retrieving decisions
48 ATH_CHECK( m_algstateSvc.retrieve() );
49
50 ATH_CHECK(m_evtStore.retrieve());
51
52 return StatusCode::SUCCESS;
53}
54
55
56StatusCode
58{
59 ATH_MSG_INFO ("Finalized successfully.");
60 return StatusCode::SUCCESS;
61}
62
63StatusCode
65{
66 StatusCode status = StatusCode::SUCCESS;
67
68 // Fill up m_streamNames vector
69 std::set<std::string> uniStreams;
70 m_streamNames.clear();
71 // first take list of streams from accept streams
72 for(auto iter = m_stream_accept.begin();
73 iter != m_stream_accept.end(); ++iter){
74 uniStreams.insert(iter->first);
75 }
76 // then require
77 for(auto iter = m_stream_require.begin();
78 iter != m_stream_require.end(); ++iter){
79 uniStreams.insert(iter->first);
80 }
81 // then veto
82 for(auto iter = m_stream_veto.begin();
83 iter != m_stream_veto.end(); ++iter){
84 uniStreams.insert(iter->first);
85 }
86 std::copy(uniStreams.begin(),uniStreams.end(),std::back_inserter(m_streamNames));
87
88 return status;
89}
90
91
93// Non-const methods:
95
96
97StatusCode
98DecisionSvc::addStream(const std::string& stream)
99{
100 StatusCode status = StatusCode::SUCCESS;
101 if(m_frozen != true){
102 // check if this stream already exist
103 auto it = m_stream_accept.find(stream);
104 if(it != m_stream_accept.end()){
105 // ok, it exists, then do nothing
106 ATH_MSG_WARNING("Stream name : {} already been registered!", stream);
107 status = StatusCode::FAILURE;
108 }else{
109 //if the stream doesn't exist yet, then insert it to the accept list with an empty vector of Algs
110 std::vector<std::string> tmpvec;
111 tmpvec.clear();
112 ATH_MSG_INFO("Inserting stream: {} with no Algs", stream);
113 m_stream_accept.insert(std::make_pair(stream, tmpvec));
114 status = StatusCode::SUCCESS;
115 }
116 }
117 return status;
118}
119
120StatusCode
121DecisionSvc::fillMap(std::map<std::string, std::vector<std::string> >& streamsModeMap,
122 const std::string& name, const std::string& stream)
123{
124 // check if this stream already exist
125 std::map<std::string, std::vector<std::string> >::iterator it = streamsModeMap.find(stream);
126 if(it != streamsModeMap.end()){
127 // ok, it exists, then check if the algname was already been inserted
128
129
130 bool algexist = false;
131 // Check if alg already registered for this stream
132 for(auto vit = (it->second).begin();
133 vit != (it->second).end(); ++vit) {
134 if((*vit) == name){
135 algexist = true;
136 // it seems the alg was already inserted, warn the user
137 ATH_MSG_ERROR("Alg name : {} of stream {} has already been registered!",
138 name, stream);
139 return StatusCode::FAILURE;
140 }
141 }
142
143
144 // So, if the stream exist but the alg has not been registered
145 // update its content std::vector with a alg
146 if(algexist == false){
147 std::vector<std::string> &tmpvec = it->second;
148 tmpvec.push_back(name);
149 }
150
151 //if the stream doesn't exist yet, then insert it
152 } else {
153 std::vector<std::string> tmpvec;
154 tmpvec.push_back(name);
155 streamsModeMap[stream] = std::move(tmpvec);
156 }
157
158 return StatusCode::SUCCESS;
159}
160
161StatusCode
162DecisionSvc::addAcceptAlg(const std::string& name, const std::string& stream)
163{
164 // Add alg to list of streams
165 auto it = std::find(m_streamNames.begin(), m_streamNames.end(),stream);
166 if (it != m_streamNames.end()) m_streamNames.push_back(stream);
167 // Fill map of stream to alg
168 return fillMap(m_stream_accept,name,stream);
169}
170
171StatusCode
172DecisionSvc::addRequireAlg(const std::string& name,
173 const std::string& stream)
174{
175 // Add alg to list of streams
176 auto it = std::find(m_streamNames.begin(), m_streamNames.end(),stream);
177 if (it != m_streamNames.end()) m_streamNames.push_back(stream);
178 // Fill map of stream to alg
179 return fillMap(m_stream_require,name,stream);
180}
181
182StatusCode
183DecisionSvc::addVetoAlg(const std::string& name,
184 const std::string& stream)
185{
186 // Add alg to list of streams
187 auto it = std::find(m_streamNames.begin(), m_streamNames.end(),stream);
188 if (it != m_streamNames.end()) m_streamNames.push_back(stream);
189 // Fill map of stream to alg
190 return fillMap(m_stream_veto,name,stream);
191}
192
193// Utility interface to retrieve unique list of streams
194const std::vector<std::string> DecisionSvc::getStreams() const
195{
196 return m_streamNames;
197}
198
199// Utility interface
200const std::vector<std::string>
201DecisionSvc::getAcceptAlgs(const std::string& stream) const
202{
203 auto iter = m_stream_accept.find(stream);
204 if (iter != m_stream_accept.end()) return iter->second;
205 return std::vector<std::string>();
206}
207
208// Utility interface
209const std::vector<std::string>
210DecisionSvc::getRequireAlgs(const std::string& stream) const
211{
212 auto iter = m_stream_require.find(stream);
213 if (iter != m_stream_require.end()) return iter->second;
214 return std::vector<std::string>();
215}
216
217// Utility interface
218const std::vector<std::string>
219DecisionSvc::getVetoAlgs(const std::string& stream) const
220{
221 auto iter = m_stream_veto.find(stream);
222 if (iter != m_stream_veto.end()) return iter->second;
223 return std::vector<std::string>();
224}
225
226
227
229// Const methods:
231
232
233bool
234DecisionSvc::isEventAccepted( const std::string& stream ) const
235{
236 EventContext ec;
237 ec.setValid(false);
238 ec.setSlot(0);
239 return isEventAccepted(stream,ec);
240}
241
242bool
243DecisionSvc::isEventAccepted( const std::string& stream,
244 const EventContext& ectx) const
245{
246
247 ATH_MSG_DEBUG("In DecisionSvc::isEventAccepted( {} )", stream);
248
249 // By construction a stream is accepted
250 bool result = true;
251
252 bool found_accept = false;
253 bool found_require = false;
254 bool found_veto = false;
255
256 //Loop over all streams of accept type and find the one of interest
257 auto itAlgs = m_stream_accept.find(stream);
258 if(itAlgs != m_stream_accept.end()){
259 found_accept = true;
260 // get a handle of the streams' algos vector
261 const auto &vecAlgs = itAlgs->second;
262 // Loop over all Algorithms in the list to see
263 // whether any have been executed and have their filter
264 // passed flag set. Any match causes the event to be
265 // provisionally accepted.
266 if ( ! vecAlgs.empty( ) ) {
267 result = false;
268 for (auto it = vecAlgs.begin(); it != vecAlgs.end(); it++) {
269 bool isE,fp;
270 isE = (m_algstateSvc->algExecState(*it,ectx).state() == AlgExecState::State::Done);
271 fp = m_algstateSvc->algExecState(*it,ectx).filterPassed();
272 if (isE && fp) {
273 result = true;
274 break;
275 }
276 }
277 }
278 }
279
280 //Loop over all streams of require type and find the one of interest
281 itAlgs = m_stream_require.find(stream);
282 if(itAlgs != m_stream_require.end()){
283 found_require = true;
284 // get a handle of the streams' algos vector
285 const auto &vecAlgs = itAlgs->second;
286 // Loop over all Algorithms in the list to see
287 // whether any have been executed and have their filter
288 // passed flag set. Any match causes the event to be
289 // provisionally accepted.
290 if ( ! vecAlgs.empty( ) ) {
291 for (auto it = vecAlgs.begin(); it != vecAlgs.end(); it++) {
292 bool isE,fp;
293 isE = (m_algstateSvc->algExecState(*it,ectx).state() == AlgExecState::State::Done);
294 fp = m_algstateSvc->algExecState(*it,ectx).filterPassed();
295 if (!isE || !fp) {
296 result = false;
297 break;
298 }
299 }
300 }
301 }
302
303 //Loop over all streams of veto type and find the one of interest
304 itAlgs = m_stream_veto.find(stream);
305 if(itAlgs != m_stream_veto.end()){
306 found_veto = true;
307 // get a handle of the streams' algos vector
308 const auto &vecAlgs = itAlgs->second;
309 // Loop over all Algorithms in the list to see
310 // whether any have been executed and have their filter
311 // passed flag set. Any match causes the event to be
312 // provisionally accepted.
313 if ( ! vecAlgs.empty( ) ) {
314 for (auto it = vecAlgs.begin(); it != vecAlgs.end(); it++) {
315 bool isE,fp;
316 isE = (m_algstateSvc->algExecState(*it,ectx).state() == AlgExecState::State::Done);
317 fp = m_algstateSvc->algExecState(*it,ectx).filterPassed();
318 if ( isE && fp ) {
319 result = false;
320 break;
321 }
322 }
323 }
324 }
325
326 if(found_accept == false && found_require == false && found_veto == false){
327 ATH_MSG_DEBUG("Stream: {} not found registered in DecisionSvc -- accepting event by default ", stream);
328 }
329
330 return result;
331}
332
333StatusCode DecisionSvc::start ATLAS_NOT_THREAD_SAFE ()
334{
335 ATH_MSG_DEBUG("in start");
336 CHECK( this->interpretAlgMap() );
337 m_frozen = true;
338
339 // lambda to return true if second element is non-empty
340 auto teststreams = [](const auto& m)
341 {
342 for (const auto& p : m)
343 if (!p.second.empty()) return true;
344 return false;
345 };
346
347 //Retrieve CutFlowSvc if (and only if) needed
348 if( teststreams(m_stream_accept) || teststreams(m_stream_require) || teststreams(m_stream_veto)) {
349 if (!m_cutflowSvc.empty())
350 {
351 if (m_cutflowSvc.retrieve().isFailure())
352 {
353 ATH_MSG_ERROR("Cannot get ICutFlowSvc interface.");
354 return StatusCode::RECOVERABLE;
355 }
356 }
357 }
358
359 //Now that everything is said and done, match filters with stream and logic in CutFlowSvc
360 return DeclareToCutFlowSvc();
361}
362
363StatusCode DecisionSvc::DeclareToCutFlowSvc ATLAS_NOT_THREAD_SAFE ()
364{
365 // Declare all decisions to CutFlowSvc for bookkeeping
366
367 // Loop over all streams
368 for(auto ait = m_streamNames.begin();
369 ait != m_streamNames.end(); ++ait) {
370 const std::string &streamName=*ait;
371 const std::vector<std::string> *accFilt=nullptr;
372 const std::vector<std::string> *reqFilt=nullptr;
373 const std::vector<std::string> *vetFilt=nullptr;
374 std::vector< const std::vector<std::string>* > totFilt;
375 if (auto itr = m_stream_accept.find(streamName); itr != m_stream_accept.end()) {
376 accFilt = &itr->second;
377 totFilt.push_back(accFilt);
378 }
379 if (auto itr = m_stream_require.find(streamName); itr != m_stream_require.end()) {
380 reqFilt = &itr->second;
381 totFilt.push_back(reqFilt);
382 }
383 if (auto itr = m_stream_veto.find(streamName); itr != m_stream_veto.end()) {
384 vetFilt = &itr->second;
385 totFilt.push_back(vetFilt);
386 }
387
388 // Now build logicalKey as string of filt ||, &&, ! based on
389 // whether it is accept, require, veto
390 std::string accstring(""), reqstring(""), vetstring("");
391 if(accFilt){
392 for (auto it = accFilt->begin(); it != accFilt->end(); ++it) {
393 if(!accstring.empty()) accstring += "||";
394 else accstring += '(';
395 accstring+=*it;
396 }
397 }
398 if(reqFilt){
399 for (auto it = reqFilt->begin(); it != reqFilt->end(); ++it) {
400 if(!reqstring.empty()) reqstring += "&&";
401 else reqstring += '(';
402 reqstring+=*it;
403 }
404 }
405 if(vetFilt){
406 for (auto it = vetFilt->begin(); it != vetFilt->end(); ++it) {
407 if(!vetstring.empty()) vetstring += "||";
408 else vetstring += '(';
409 vetstring+=*it;
410 }
411 }
412 std::string logicalKey("");
413 if(!accstring.empty()) {
414 accstring += ')';
415 logicalKey += accstring;
416 }
417 if(!reqstring.empty()) {
418 reqstring += ')';
419 if (!logicalKey.empty()) logicalKey += "&&";
420 logicalKey += reqstring;
421 }
422 if(!vetstring.empty()) {
423 vetstring += ')';
424 if (!logicalKey.empty()) logicalKey += "&&";
425 logicalKey += '!';
426 logicalKey += vetstring;
427 }
428 // If no filters, mark as PasThru
429 if (logicalKey.empty()) logicalKey="PassThru";
430 ATH_MSG_DEBUG("stream {} uses logic {}", streamName, logicalKey);
431
432 // Now actually declare to the cutflowsvc
433 for(auto vec = totFilt.begin();
434 vec != totFilt.end(); ++vec) {
435 ATH_MSG_DEBUG("Declaring logic {} for {}", logicalKey, streamName);
436 for (auto filter = (*vec)->begin();
437 filter != (*vec)->end(); ++filter) {
438 if(!m_cutflowSvc.empty()) {m_cutflowSvc->registerTopFilter( (*filter), logicalKey, 2, streamName, true ); } // TODO: validate
439 }
440 }
441 }
442
443 return StatusCode::SUCCESS;
444}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
std::vector< size_t > vec
#define CHECK(...)
Evaluate an expression and check for errors.
StatusCode DecisionSvc::start ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
An AttributeList represents a logical row of attributes in a metadata table.
std::map< std::string, std::vector< std::string > > m_stream_accept
Maps of streams – algorithm names' vectors.
Definition DecisionSvc.h:89
virtual StatusCode finalize() override
virtual StatusCode addRequireAlg(const std::string &name, const std::string &stream) override
Add an algorithm to the list of RequireAlgs of a stream.
virtual const std::vector< std::string > getAcceptAlgs(const std::string &stream) const override
Return list of AcceptAlg names.
virtual ~DecisionSvc()
Destructor.
ServiceHandle< StoreGateSvc > m_evtStore
Definition DecisionSvc.h:97
ServiceHandle< ICutFlowSvc > m_cutflowSvc
Definition DecisionSvc.h:98
std::vector< std::string > m_streamNames
Definition DecisionSvc.h:93
virtual StatusCode addAcceptAlg(const std::string &name, const std::string &stream) override
Add an algorithm to the list of AcceptAlgs of a stream.
DecisionSvc(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
virtual StatusCode addVetoAlg(const std::string &name, const std::string &stream) override
Add an algorithm to the list of VetoAlgs of a stream.
virtual StatusCode initialize() override
Gaudi Service Implementation.
virtual const std::vector< std::string > getVetoAlgs(const std::string &stream) const override
Return list of VetoAlg names.
std::map< std::string, std::vector< std::string > > m_stream_require
Definition DecisionSvc.h:90
std::map< std::string, std::vector< std::string > > m_stream_veto
Definition DecisionSvc.h:91
virtual StatusCode addStream(const std::string &stream) override
Add a stream.
virtual bool isEventAccepted(const std::string &stream) const override
Test whether this event should be output.
virtual const std::vector< std::string > getRequireAlgs(const std::string &stream) const override
Return list of RequireAlg names.
virtual const std::vector< std::string > getStreams() const override
Return list of Streams.
StatusCode fillMap(std::map< std::string, std::vector< std::string > > &streamsModeMap, const std::string &name, const std::string &stream)
ServiceHandle< IAlgExecStateSvc > m_algstateSvc
Definition DecisionSvc.h:99
StatusCode interpretAlgMap()
::StatusCode StatusCode
StatusCode definition for legacy code.