ATLAS Offline Software
Loading...
Searching...
No Matches
TrigDecisionMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5/**************************************************************************
6 **
7 ** File: TrigDecisionMaker.h
8 **
9 ** Description: - Algorithm-derived class to run after the Steering to create the
10 ** transient TrigDecision object
11 **
12 **
13 **
14 * @author Nicolas Berger <Nicolas.Berger@cern.ch> - CERN
15 * @author Till Eifert <Till.Eifert@cern.ch> - U. of Geneva, Switzerland
16 * @author Ricardo Goncalo <Jose.Goncalo@cern.ch> - Royal Holloway, U. of London
17 **
18 ** Created: Tue May 09 14:55:56 GMT 2006
19 ** Modified:
20 **
21 **************************************************************************/
22
23#include "TrigDecisionMaker.h"
24
26
28
29
30// all Trigger EDM ()
31
32
33using namespace TrigDec;
34
35TrigDecisionMaker::TrigDecisionMaker(const std::string &name, ISvcLocator *pSvcLocator)
36 : AthReentrantAlgorithm(name, pSvcLocator),
37 m_nEvents(0),
39 m_hlt_error(0),
40 m_td_error(0), m_td_skip(0),
44 m_hlt_notReq(0),
47{
48}
49
50
52
53
55{
56 m_nEvents = 0;
57 m_l1_error = 0;
58 m_l2_error = 0;
59 m_ef_error = 0;
60 m_hlt_error = 0;
61 m_td_error = 0;
62 m_td_skip = 0;
63 m_l1_notFound = 0;
64 m_l2_notFound = 0;
65 m_ef_notFound = 0;
67 m_l1_notReq = 0;
68 m_l2_notReq = 0;
69 m_ef_notReq = 0;
70 m_hlt_notReq = 0;
71 m_l1_passed = 0;
72 m_l2_passed = 0;
73 m_ef_passed = 0;
74 m_hlt_passed = 0;
75
76 ATH_MSG_DEBUG ( "Initializing TrigDecisionMaker..." ) ;
77 ATH_MSG_DEBUG ( "Properties:" ) ;
78 ATH_MSG_DEBUG ( " doL1 = " << (m_doL1 ? "True":"False") ) ;
79 ATH_MSG_DEBUG ( " doL2 = " << (m_doL2 ? "True":"False") ) ;
80 ATH_MSG_DEBUG ( " doEF = " << (m_doEF ? "True":"False") ) ;
81 ATH_MSG_DEBUG ( " doHLT = " << (m_doHLT ? "True":"False") ) ;
82 ATH_MSG_DEBUG ( " TrigDecisionKey = " << m_trigDecisionKey ) ;
83 ATH_MSG_DEBUG ( " TrigL1ResultKey = " << m_l1ResultKey ) ;
84 ATH_MSG_DEBUG ( " TrigROIBL1ResultKey = " << m_l1roibResultKey ) ;
85 ATH_MSG_DEBUG ( " TrigL2ResultKey = " << m_l2ResultKey ) ;
86 ATH_MSG_DEBUG ( " TrigEFResultKey = " << m_efResultKey ) ;
87 ATH_MSG_DEBUG ( " TrigHLTResultKey= " << m_hltResultKey ) ;
88
89 ATH_CHECK( m_lvl1Tool.retrieve() );
90
91 ATH_CHECK( m_bgKey.initialize() );
92 ATH_CHECK( m_HLTMenuKey.initialize() );
93 ATH_CHECK( m_trigDecisionKey.initialize() );
95 ATH_CHECK( m_l1roibResultKey.initialize(m_doL1 && m_l1ResultKey.empty()) );
96 ATH_CHECK( m_l2ResultKey.initialize(m_doL2) );
97 ATH_CHECK( m_efResultKey.initialize(m_doEF) );
98 ATH_CHECK( m_hltResultKey.initialize(m_doHLT) );
99
100 return StatusCode::SUCCESS;
101}
102
103
104
106{
107 // print out stats: use also to do regression tests
108 ATH_MSG_DEBUG ("=============================================" ) ;
109 ATH_MSG_DEBUG ("REGTEST Run summary:" ) ;
110 ATH_MSG_DEBUG ("REGTEST Events processed : " << m_nEvents ) ;
111
112 ATH_MSG_DEBUG ("REGTEST Level 1 : passed = " << m_l1_passed ) ;
113 ATH_MSG_DEBUG ("REGTEST Level 1 : not found = " << m_l1_notFound ) ;
114 ATH_MSG_DEBUG ("REGTEST Level 1 : not requested = " << m_l1_notReq ) ;
115 ATH_MSG_DEBUG ("REGTEST Level 1 : SG errors = " << m_l1_error ) ;
116
117 ATH_MSG_DEBUG ("REGTEST Level 2 : passed = " << m_l2_passed ) ;
118 ATH_MSG_DEBUG ("REGTEST Level 2 : not found = " << m_l2_notFound ) ;
119 ATH_MSG_DEBUG ("REGTEST Level 2 : not requested = " << m_l2_notReq ) ;
120 ATH_MSG_DEBUG ("REGTEST Level 2 : SG errors = " << m_l2_error ) ;
121
122 ATH_MSG_DEBUG ("REGTEST EvFilter : passed = " << m_ef_passed ) ;
123 ATH_MSG_DEBUG ("REGTEST EvFilter : not found = " << m_ef_notFound ) ;
124 ATH_MSG_DEBUG ("REGTEST EvFilter : not requested = " << m_ef_notReq ) ;
125 ATH_MSG_DEBUG ("REGTEST EvFilter : SG errors = " << m_ef_error ) ;
126
127 ATH_MSG_DEBUG ("REGTEST HLT : passed = " << m_hlt_passed ) ;
128 ATH_MSG_DEBUG ("REGTEST HLT : not found = " << m_hlt_notFound ) ;
129 ATH_MSG_DEBUG ("REGTEST HLT : not requested = " << m_hlt_notReq ) ;
130 ATH_MSG_DEBUG ("REGTEST HLT : SG errors = " << m_hlt_error ) ;
131
132 ATH_MSG_DEBUG ("REGTEST TrigDecision not written : " << m_td_skip ) ;
133 ATH_MSG_DEBUG ("REGTEST SG errors in storing TD : " << m_td_error ) ;
134 ATH_MSG_DEBUG ("=============================================" ) ;
135
136 return StatusCode::SUCCESS;
137}
138
139
140StatusCode TrigDecisionMaker::execute(const EventContext& ctx) const
141{
142 // increment event counter
143 m_nEvents++;
144
145 // Retrieve the results
146 const LVL1CTP::Lvl1Result* l1Result = 0;
147 const HLT::HLTResult* l2Result = 0;
148 const HLT::HLTResult* efResult = 0;
149 const HLT::HLTResult* hltResult = 0;
150
151 ResultStatus l1Stat = getL1Result(l1Result, ctx);
152 if (!l1Result) {
153 if (l1Stat == NotRequested ) m_l1_notReq++;
154 else if (l1Stat == SGError || l1Stat == ProcError) m_l1_error++;
155 else if (l1Stat == NotFound) m_l1_notFound++;
156 }
157 else if (l1Result->isAccepted()) m_l1_passed++;
158
159 ResultStatus l2Stat = getHLTResult(l2Result, L2, ctx);
160 if (!l2Result) {
161 if (l2Stat == NotRequested ) m_l2_notReq++;
162 else if (l2Stat == SGError || l2Stat == ProcError) m_l2_error++;
163 else if (l2Stat == NotFound) m_l2_notFound++;
164 }
165 else if (l2Result->isAccepted()) m_l2_passed++;
166
167 ResultStatus efStat = getHLTResult(efResult, EF, ctx);
168 if (!efResult) {
169 if (efStat == NotRequested ) m_ef_notReq++;
170 else if (efStat == SGError || efStat == ProcError) m_ef_error++;
171 else if (efStat == NotFound) m_ef_notFound++;
172 }
173 else if (efResult->isAccepted()) m_ef_passed++;
174
175
176 ResultStatus hltStat = getHLTResult(hltResult, HLT, ctx);
177 if (!hltResult) {
178 if (hltStat == NotRequested ) m_hlt_notReq++;
179 else if (hltStat == SGError || hltStat == ProcError) m_hlt_error++;
180 else if (hltStat == NotFound) m_hlt_notFound++;
181 }
182 else if (hltResult->isAccepted()) m_hlt_passed++;
183
184
185 if (!l1Result && !l2Result && !efResult && !hltResult) {
186 ATH_MSG_ERROR ("The whole trigger seems off for this event (no L1/L2/EF/HLT results) - no TrigDecision produced");
187 m_td_skip++;
188 return StatusCode::SUCCESS;
189 }
190
191 std::unique_ptr<TrigDecision> trigDec = std::make_unique<TrigDecision>();
192
194 ATH_CHECK( hltMenu.isValid() );
195 trigDec->m_configMasterKey = hltMenu->smk();
196
197 if (l1Result) trigDec->m_l1_result = *l1Result;
198 if (l2Result) trigDec->m_l2_result = *l2Result;
199 if (efResult) trigDec->m_ef_result = *efResult;
200 if (hltResult){
201 trigDec->m_ef_result = *hltResult;//store the merged result into ef_result to propagate with getEFResult
202 }
203
204 // get the bunch crossing id
205 ATH_MSG_DEBUG ( "Run " << ctx.eventID().run_number()
206 << "; Event " << ctx.eventID().event_number()
207 << "; BC-ID " << ctx.eventID().bunch_crossing_id() ) ;
209 ATH_CHECK(bgkey.isValid());
210 const TrigConf::L1BunchGroupSet* l1bgs = *bgkey;
211 if (l1bgs) {
212 // We currently only support 8 bits/bunchgroups (ATR-24030)
213 trigDec->m_bgCode = static_cast<char>(l1bgs->bgPattern(ctx.eventID().bunch_crossing_id()));
214 }
215 else {
216 ATH_MSG_WARNING("Could not read " << m_bgKey);
217 }
218
220 if (writeHandle.record(std::move(trigDec)).isFailure()) {
221 ATH_MSG_ERROR ( "Failed to record TrigDecision to StoreGate with key "
222 << m_trigDecisionKey << "!" ) ;
223
224 m_td_error++;
225 return StatusCode::FAILURE;
226 }
227
228 ATH_MSG_DEBUG ( "Recorded TrigDecision to StoreGate with key = "
229 << m_trigDecisionKey << "." ) ;
230
231
232 return StatusCode::SUCCESS;
233}
234
236{
237 result = 0;
238 if (!m_doL1) return NotRequested;
239
240 if (!m_l1ResultKey.empty())
241 {
243 if (l1RH.isValid()) {
244 result = l1RH.cptr();
245 return OK;
246 }
247 else
248 {
249 result = nullptr;
250 ATH_MSG_WARNING( "Configured to retrieve L1 from LVL1CTP::Lvl1Result but this was not found");
251 return NotFound;
252 }
253 }
254
256 if (!l1roibRH.isValid()) {
257 result = nullptr;
258 ATH_MSG_WARNING ( "Trying to do L1, but RoIBResult not found" ) ;
259 return NotFound;
260 }
261
262 const ROIB::RoIBResult* roIBResult = l1roibRH.cptr();
263
264 ATH_MSG_DEBUG ( "Got ROIBResult from StoreGate with key " << m_l1roibResultKey ) ;
265
266 std::vector< std::unique_ptr<LVL1CTP::Lvl1Item> > itemConfig = m_lvl1Tool->makeLvl1ItemConfig(ctx);
267
268 if ((roIBResult->cTPResult()).isComplete()) {
269 m_lvl1Tool->createL1Items(itemConfig, *roIBResult,&result);
270 ATH_MSG_DEBUG ( "Build LVL1CTP::Lvl1Result from valid CTPResult.") ;
271 } else {
272 ATH_MSG_DEBUG ( "No LVL1CTP::Lvl1Result build since no valid CTPResult is available.") ;
273 }
274
275 return OK;
276}
277
278
280 TrigLevel level, const EventContext& ctx) const
281{
282 result = 0;
283
284 if (level != L2 && level != EF && level != HLT) {
285 ATH_MSG_ERROR ("Level must be either L2 or EF or HLT in getHLTResult!");
286 return Unknown;
287 }
288
289 if ((level == L2 && !m_doL2) || (level == EF && !m_doEF) || (level == HLT && !m_doHLT)) return NotRequested;
290
291 const SG::ReadHandleKey<HLT::HLTResult>& key = (level == L2 ? m_l2ResultKey : (level == EF) ? m_efResultKey : m_hltResultKey);
292
293 SG::ReadHandle<HLT::HLTResult> hltRH{key, ctx};
294
295 if (!hltRH.isValid()) {
296 ATH_MSG_ERROR ( "Error retrieving HLTResult from StoreGate" ) ;
297 result = nullptr;
298 return SGError;
299 }
300
301 result = hltRH.cptr();
302
303 ATH_MSG_DEBUG ( "Got HLTResult from StoreGate with key " << key ) ;
304
305 return OK;
306}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An algorithm that can be simultaneously executed in multiple threads.
HLT::HLTResult is sumarising result of trigger decision evaluation (online/offline) It contains basic...
Definition HLTResult.h:51
bool isAccepted() const
gets HLT decision
Definition HLTResult.h:131
bool isAccepted() const
final LVL1 decision && isConfigured
Class holding the LVL1 RoIB result build by the RoIBuilder.
Definition RoIBResult.h:47
const CTPResult & cTPResult() const
Gets the CTP part of the L1 RDO.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
L1 board configuration.
bgPattern_t bgPattern(size_t bcid) const
Return word with bit-pattern of fired bunchgroups for given bcid.
virtual StatusCode finalize() override
std Gaudi finalize method -> print out statistics
SG::ReadHandleKey< ROIB::RoIBResult > m_l1roibResultKey
std::atomic< unsigned int > m_l2_error
SG::ReadHandleKey< HLT::HLTResult > m_l2ResultKey
std::atomic< unsigned int > m_ef_notFound
std::atomic< unsigned int > m_nEvents
statistics: number of processed events
std::atomic< unsigned int > m_td_skip
statistics: error numbers
std::atomic< unsigned int > m_l2_passed
Gaudi::Property< bool > m_doHLT
std::atomic< unsigned int > m_ef_error
virtual StatusCode initialize() override
std Gaudi initialize method -> read-in trigger configuration
SG::ReadHandleKey< TrigConf::HLTMenu > m_HLTMenuKey
std::atomic< unsigned int > m_hlt_error
Gaudi::Property< bool > m_doEF
std::atomic< unsigned int > m_hlt_notReq
statistics: number of events where something was not requested
SG::ReadHandleKey< HLT::HLTResult > m_hltResultKey
std::atomic< unsigned int > m_l1_notReq
std::atomic< unsigned int > m_l1_error
virtual StatusCode execute(const EventContext &ctx) const override
std Gaudi execute method -> fill event-wise TrigDecision object, save in SG
TrigDecisionMaker(const std::string &name, ISvcLocator *pSvcLocator)
std Gaudi Algorithm constructor
ResultStatus getHLTResult(const HLT::HLTResult *&result, TrigLevel level, const EventContext &ctx) const
retrieve HLT results (called in execute)
std::atomic< unsigned int > m_hlt_notFound
statistics: number of events where L1, HLT results were not found
std::atomic< unsigned int > m_hlt_passed
statistics: number of events that passed the given trigger lvl
std::atomic< unsigned int > m_l2_notReq
std::atomic< unsigned int > m_ef_notReq
SG::ReadHandleKey< HLT::HLTResult > m_efResultKey
SG::ReadHandleKey< LVL1CTP::Lvl1Result > m_l1ResultKey
Gaudi::Property< bool > m_doL2
SG::WriteHandleKey< TrigDecision > m_trigDecisionKey
std::atomic< unsigned int > m_l1_passed
Gaudi::Property< bool > m_doL1
ToolHandle< HLT::ILvl1ResultAccessTool > m_lvl1Tool
tool to ease the access to the L1 results (RoIs, items, etc)
virtual ~TrigDecisionMaker()
std deconstructor
ResultStatus getL1Result(const LVL1CTP::Lvl1Result *&result, const EventContext &ctx) const
retrieve LVL1 result (called in execute)
SG::ReadCondHandleKey< TrigConf::L1BunchGroupSet > m_bgKey
std::atomic< unsigned int > m_l1_notFound
std::atomic< unsigned int > m_td_error
std::atomic< unsigned int > m_l2_notFound
std::atomic< unsigned int > m_ef_passed
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...