ATLAS Offline Software
Loading...
Searching...
No Matches
RoIBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// STL includes:
7#include <iomanip>
8#include <vector>
9
10// Gaudi/Athena includes:
12
14
15// eformat include:
16#include "eformat/SourceIdentifier.h"
17
18// TrigT1 includes:
20
21// Local includes:
22#include "RoIBuilder.h"
23#include "RoIBDefs.h"
24
25namespace ROIB {
26
27 //---------------------------------
28 // initialize()
29 //---------------------------------
31
32 ATH_MSG_INFO( "========================================" );
33 ATH_MSG_INFO( "Initialisation for RoIBuilder algorithm." );
34 ATH_MSG_INFO( "========================================" );
35 // Print system info
36 if( ! m_doCalo ) {
37 ATH_MSG_WARNING( "Inputs from LVL1 Calo systems switched off" );
38 }
39 if( ! m_doMuon ) {
40 ATH_MSG_WARNING("Inputs from LVL1 Muon systems switched off" );
41 }
42
43 CHECK( m_eventInfoKey.initialize() );
44
45 if ( m_doCalo ) {
46 CHECK( not m_caloEMTauLocation.empty() );
47 CHECK( not m_caloJetEnergyLocation.empty() );
48 } else {
51 }
52 CHECK( m_caloEMTauLocation.initialize() );
53 CHECK( m_caloJetEnergyLocation.initialize() );
54
55
56 if ( m_doMuon ) {
57 CHECK( not m_muctpiSLinkLocation.key().empty() );
58 } else {
60 }
61 CHECK( m_muctpiSLinkLocation.initialize() );
62
63 CHECK( m_ctpSLinkLocation.initialize() );
64 CHECK( m_roibRDOLocation.initialize() );
65
66 return StatusCode::SUCCESS;
67 }
68
69 //----------------------------------------------
70 // execute() method called once per event
71 //----------------------------------------------
72 StatusCode RoIBuilder::execute(const EventContext& ctx) const {
73
74 // Exec message
75 ATH_MSG_DEBUG( "============================" );
76 ATH_MSG_DEBUG( "Execution of RoIB algorithm." );
77 ATH_MSG_DEBUG( "============================" );
78
79 //
80 // Get the official event ID:
81 //
82
83 auto eventInfoHandle = SG::makeHandle( m_eventInfoKey, ctx );
84 CHECK( eventInfoHandle.isValid() );
85 const xAOD::EventInfo* thisEvent = eventInfoHandle.cptr();
86 // Note we are loosing precision here as we cast from 64 to 32 bits integer
87 // but this is constraint imposed by: Trigger/TrigT1/TrigT1Result/TrigT1Result/Header.h
88 const int evtNum = static_cast<int>(thisEvent->eventNumber());
89 ATH_MSG_VERBOSE( "Event number is: " << evtNum );
90
91
93 // //
94 // CTP RoI //
95 // //
97
98 // create the header
99 Header ctp_rdo_header( eformat::helper::SourceIdentifier( eformat::TDAQ_CTP,
100 0 ).code() );
101
102 // create zero data trailer
103 Trailer ctp_rdo_trailer( 0 );
104
105 // create data element
106 std::vector< unsigned int > ctp_rdo_data;
107
108 bool ctp_simulation_error = false;
109 auto ctpSlinkHandle = SG::makeHandle( m_ctpSLinkLocation, ctx );
110 CHECK( ctpSlinkHandle.isValid() );
111 const LVL1CTP::CTPSLink* ctp_slink = ctpSlinkHandle.cptr();
112
113 // test for consistency
114 if ( ctp_slink->getCTPToRoIBWords().empty() ) {
115 ctp_simulation_error = true;
116 REPORT_MESSAGE( MSG::WARNING ) << "CTP size is zero. No header, trailer, data element";
117 } else if( ctp_slink->getDataElements().size() != ctp_slink->getNumWordsPerCTPSLink() ) {
118 ctp_simulation_error = true;
119 REPORT_MESSAGE( MSG::WARNING )
120 << "Found CTP size inconsistency: "
121 << ctp_slink->getDataElements().size() << "/"
122 //<< LVL1CTP::CTPSLink::wordsPerCTPSLink
123 << ctp_slink->getNumWordsPerCTPSLink()
124 << " (found/expected)";
125
126 // get the data elements
127 if( msgLvl( MSG::DEBUG ) ) {
128 const std::vector< unsigned int > ctp_rdo_data_inc = ctp_slink->getDataElements();
129 for( size_t i(0); i < ctp_rdo_data_inc.size(); ++i ) {
130 ATH_MSG_DEBUG( "broken CTP RoI = " << std::setw( 2 ) << i << ' '
131 << MSG::hex << std::setfill('0') << std::setw( 8 )
132 << ctp_rdo_data_inc[i]
133 << MSG::dec << std::setfill(' ') );
134 }
135 }
136 } else {
137 ATH_MSG_VERBOSE( "Retrieved CTP result from TES with key: "
139 }
140
141 if( ctp_simulation_error ) {
142
143 REPORT_MESSAGE( MSG::WARNING )
144 << "Creating empty CTP RDO with error code!";
145 ctp_rdo_trailer.setSimulationError();
146
147 } else {
148
149 // prepare header
150 ctp_rdo_header = Header(std::vector<uint32_t>(ctp_slink->getHeader()));
151
152 // get the data elements
153 ctp_rdo_data = ctp_slink->getDataElements();
154 if( msgLvl( MSG::DEBUG ) ) {
155 for (size_t i(0); i < ctp_rdo_data.size(); ++i) {
156 ATH_MSG_DEBUG( "CTP RoI = " << MSG::dec << std::setw( 2 ) << i
157 << " 0x" << MSG::hex << std::setfill('0') << std::setw( 8 )
158 << ctp_rdo_data[i]
159 << MSG::dec << std::setfill(' ') );
160 }
161 }
162
163 // prepare trailer
164 ctp_rdo_trailer = Trailer(std::vector<uint32_t>(ctp_slink->getTrailer()));
165 }
166
167 // build result
168 CTPResult ctp_rdo_result( ctp_slink->getCTPVersionNumber(), std::move(ctp_rdo_header),
169 std::move(ctp_rdo_trailer), ctp_rdo_data ); //ctp_rdo_data is not moved because it needs to be converted
170 ATH_MSG_VERBOSE( "Dump CTPResult object:\n" + ctp_rdo_result.dump() );
171
172 //
173 // Check whether the event was accepted or not:
174 //
175 bool accept = ctp_slink->getAccept();
176 ATH_MSG_DEBUG( "L1 Accept = " << accept );
177
179 // //
180 // egamma RoI //
181 // //
183
184 std::vector< EMTauResult > emtau_rdo_result_vector;
185
186
187 for( unsigned int slink = 0; slink < numEMTauSlinks; ++slink ) {
188
189 eformat::helper::SourceIdentifier
190 emtau_source_id( eformat::TDAQ_CALO_CLUSTER_PROC_ROI, slink );
191 Header emtau_rdo_header( emtau_source_id.code(), evtNum );
192 std::vector< EMTauRoI > emtau_rdo_data;
193
194 bool emtau_simulation_error = false;
195 const DataVector< LVL1CTP::SlinkWord >* emtau_slink = 0;
196
197 if( m_doCalo ) {
198 ATH_MSG_VERBOSE("Reading " << m_caloEMTauLocation[slink].key() );
199 auto handle = SG::makeHandle( m_caloEMTauLocation[slink], ctx );
200 CHECK( handle.isValid() );
201 emtau_slink = handle.cptr();
202
203 unsigned int icnt = 0;
205 emtau_slink->begin();
207 emtau_slink->end();
208 for( ; itr != end; ++itr ) {
209 ++icnt;
210 if( ( icnt > ( wordsPerHeader + 1 ) ) &&
211 ( icnt <= ( emtau_slink->size() - wordsPerTrailer - 1 ) ) ) {
212
213 EMTauRoI emtau_roi( ( *itr )->word() );
214 emtau_rdo_data.push_back( emtau_roi );
215 ATH_MSG_DEBUG( "EmTau RoI = " << MSG::hex << std::setw( 8 )
216 << emtau_roi.roIWord() );
217 }
218 }
219
220 } else {
221 emtau_simulation_error = true;
222 ATH_MSG_VERBOSE( "Retrieved EMTau Slink from TES with key: " << m_caloEMTauLocation[slink] );
223 }
224
225
226
227 Trailer emtau_rdo_trailer( 0, 0 );
228 if( ! emtau_simulation_error ) {
229 emtau_rdo_trailer.setNumDataWords( emtau_rdo_data.size() );
230 } else {
231 emtau_rdo_trailer.setSimulationError();
232 }
233
234 EMTauResult emtau_rdo_result( std::move(emtau_rdo_header), std::move(emtau_rdo_trailer),
235 std::move(emtau_rdo_data) );
236
237 emtau_rdo_result_vector.push_back( std::move(emtau_rdo_result) );
238 }
239
241 // //
242 // jet/energy RoI //
243 // //
245
246 std::vector< JetEnergyResult > jetenergy_rdo_result_vector;
247
248 for( unsigned int slink = 0; slink < numJetEnergySlinks; ++slink ) {
249
250 eformat::helper::SourceIdentifier
251 jetenergy_source_id( eformat::TDAQ_CALO_JET_PROC_ROI, slink );
252 Header jetenergy_rdo_header( jetenergy_source_id.code(), evtNum );
253 std::vector< JetEnergyRoI > jetenergy_rdo_data;
254
255 bool jetenergy_simulation_error = false;
256 const DataVector< LVL1CTP::SlinkWord >* jetenergy_slink = 0;
257
258 if( m_doCalo ) {
259 auto handle = SG::makeHandle( m_caloJetEnergyLocation[slink], ctx );
260 CHECK( handle.isValid() );
261 jetenergy_slink = handle.cptr();
262
263 ATH_MSG_VERBOSE( "Retrieved JetEnergy Slink from TES with key: "
264 << m_caloJetEnergyLocation[slink] );
265
266 unsigned int icnt = 0;
268 jetenergy_slink->begin();
270 jetenergy_slink->end();
271 for( ; itr != end; ++itr ) {
272
273 ++icnt;
274 if( ( icnt > ( wordsPerHeader + 1 ) ) &&
275 ( icnt <= ( jetenergy_slink->size() - wordsPerTrailer - 1 ) ) ) {
276
277 JetEnergyRoI jetenergy_roi( ( *itr )->word() );
278 jetenergy_rdo_data.push_back( jetenergy_roi );
279 ATH_MSG_DEBUG( "Jet/Energy RoI = " << MSG::hex << std::setw( 8 )
280 << jetenergy_roi.roIWord() );
281 }
282 }
283 } else {
284 jetenergy_simulation_error = true;
285 }
286
287
288
289 // Now wrap up the jet energy triggers:
290 Trailer jetenergy_rdo_trailer( 0, 0 );
291 if( !jetenergy_simulation_error ) {
292 jetenergy_rdo_trailer.setNumDataWords( jetenergy_rdo_data.size() );
293 } else {
294 jetenergy_rdo_trailer.setSimulationError();
295 }
296
297 JetEnergyResult jetenergy_rdo_result( std::move(jetenergy_rdo_header),
298 std::move(jetenergy_rdo_trailer),
299 std::move(jetenergy_rdo_data) );
300
301 jetenergy_rdo_result_vector.push_back( std::move(jetenergy_rdo_result) );
302 }
303
305 // //
306 // muon RoI //
307 // //
309
310 eformat::helper::SourceIdentifier
311 muon_source_id( eformat::TDAQ_MUON_CTP_INTERFACE, 0 );
312 Header muctpi_rdo_header( muon_source_id.code(), evtNum );
313 std::vector< MuCTPIRoI > muctpi_rdo_data;
314
315 bool muctpi_simulation_error = false;
316 const L1MUINT::MuCTPIToRoIBSLink* muctpi_slink = 0;
317
318 if( m_doMuon ) {
319 auto handle = SG::makeHandle( m_muctpiSLinkLocation, ctx );
320 CHECK( handle.isValid() );
321 muctpi_slink = handle.cptr();
322 ATH_MSG_VERBOSE( "Retrieved MuCTPI result from TES with key: "
324
325 unsigned int icnt = 0;
326 std::vector< unsigned int >::const_iterator itr =
327 muctpi_slink->getMuCTPIToRoIBWords().begin();
328 std::vector< unsigned int >::const_iterator end =
329 muctpi_slink->getMuCTPIToRoIBWords().end();
330 for( ; itr != end; ++itr ) {
331
332 ++icnt;
333 if( ( icnt > ( wordsPerHeader + 1 ) ) &&
334 ( icnt <= ( muctpi_slink->getMuCTPIToRoIBWords().size() -
335 wordsPerTrailer ) ) ) {
336
337 MuCTPIRoI muctpi_roi( *itr );
338 muctpi_rdo_data.push_back( muctpi_roi );
339 ATH_MSG_DEBUG( "MuCTPI RoI = " << MSG::hex << std::setw( 8 )
340 << muctpi_roi.roIWord() );
341 }
342 }
343 } else {
344 muctpi_simulation_error = true;
345 }
346
347
348
349 Trailer muctpi_rdo_trailer( 0, 0 );
350 if( ! muctpi_simulation_error ) {
351 muctpi_rdo_trailer.setNumDataWords( muctpi_rdo_data.size() );
352 } else {
353 muctpi_rdo_trailer.setSimulationError();
354 }
355
356 MuCTPIResult muctpi_rdo_result( std::move(muctpi_rdo_header), std::move(muctpi_rdo_trailer),
357 std::move(muctpi_rdo_data) );
358
359 //
360 // Finally create RoIB RDO object:
361 //
362 std::unique_ptr<RoIBResult> roib_rdo_result = std::make_unique< RoIBResult>(
363 std::move(muctpi_rdo_result),
364 std::move(ctp_rdo_result),
365 std::move(jetenergy_rdo_result_vector),
366 std::move(emtau_rdo_result_vector) );
367 if( msgLvl( MSG::DEBUG ) ) {
368 ATH_MSG_DEBUG( "RoIB Results:" );
369 roib_rdo_result->muCTPIResult().dumpData( msg( MSG::DEBUG ) );
370 // roib_rdo_result->eMTauResult();
371 // roib_rdo_result->jetEnergyResult();
372 ATH_MSG_DEBUG( roib_rdo_result->cTPResult().dump() );
373 }
374
375 //
376 // Put RoIB RDO object into SG:
377 //
378 auto roibHandle = SG::makeHandle( m_roibRDOLocation, ctx );
379 CHECK( roibHandle.record( std::move( roib_rdo_result ) ) );
380 // no owerwrite possible with DataHandles
381
382 return StatusCode::SUCCESS;
383 }
384
385} // namespace ROIB
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
#define CHECK(...)
Evaluate an expression and check for errors.
An STL vector of pointers that by default owns its pointed-to elements.
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
void renounceArray(SG::VarHandleKeyArray &handlesArray)
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
Class holding the LVL1 CTP result used by the RoIBuilder.
const std::string dump() const
dump raw object content to string
Definition CTPResult.cxx:56
uint32_t roIWord() const
Definition EMTauRoI.cxx:32
Header models the LVL1 ROD Header.
uint32_t roIWord() const
Method returning the RoI word.
Class holding the RoIs from the MuCTPI collected by the RoIB.
Class for storing the 32-bit muon RoI word.
Definition MuCTPIRoI.h:39
uint32_t roIWord() const
Method returning the RoI word.
Definition MuCTPIRoI.cxx:35
Gaudi::Property< bool > m_doCalo
Definition RoIBuilder.h:46
SG::ReadHandleKeyArray< SlinkWordDV > m_caloEMTauLocation
Definition RoIBuilder.h:57
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition RoIBuilder.h:55
SG::WriteHandleKey< RoIBResult > m_roibRDOLocation
Definition RoIBuilder.h:73
Gaudi::Property< bool > m_doMuon
Definition RoIBuilder.h:47
SG::ReadHandleKey< L1MUINT::MuCTPIToRoIBSLink > m_muctpiSLinkLocation
Definition RoIBuilder.h:69
virtual StatusCode execute(const EventContext &ctx) const override
virtual StatusCode initialize() override
SG::ReadHandleKeyArray< SlinkWordDV > m_caloJetEnergyLocation
Definition RoIBuilder.h:64
SG::ReadHandleKey< LVL1CTP::CTPSLink > m_ctpSLinkLocation
Definition RoIBuilder.h:50
ROIB::Trailer models the LVL1 ROD Trailer.
Definition Trailer.h:37
void setSimulationError()
set error status to 0xffff0000 for ROD was not found in SG
void setNumDataWords(const unsigned int)
set number of data words
uint64_t eventNumber() const
The current event's event number.
Namespace of the LVL1 RoIB simulation.
static const unsigned int wordsPerTrailer
Definition RoIBDefs.h:32
static const unsigned int wordsPerHeader
Definition RoIBDefs.h:29
static const unsigned int numEMTauSlinks
Definition RoIBDefs.h:24
static const unsigned int numJetEnergySlinks
Definition RoIBDefs.h:26
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
EventInfo_v1 EventInfo
Definition of the latest event info version.