ATLAS Offline Software
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 
25 namespace 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 
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  }
62 
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: "
138  << m_ctpSLinkLocation );
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
ROIB::RoIBuilder::initialize
virtual StatusCode initialize() override
Definition: RoIBuilder.cxx:30
RoIBDefs.h
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ROIB::RoIBuilder::m_caloJetEnergyLocation
SG::ReadHandleKeyArray< SlinkWordDV > m_caloJetEnergyLocation
Definition: RoIBuilder.h:64
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
ROIB::EMTauResult
Definition: EMTauResult.h:25
ROIB::RoIBuilder::m_ctpSLinkLocation
SG::ReadHandleKey< LVL1CTP::CTPSLink > m_ctpSLinkLocation
Definition: RoIBuilder.h:50
ROIB::RoIBuilder::m_doMuon
Gaudi::Property< bool > m_doMuon
Definition: RoIBuilder.h:47
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
RoIBuilder.h
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounce
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)
Definition: AthCommonDataStore.h:380
ROIB::Trailer::setNumDataWords
void setNumDataWords(const unsigned int)
set number of data words
ROIB::Trailer::setSimulationError
void setSimulationError()
set error status to 0xffff0000 for ROD was not found in SG
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
ROIB::MuCTPIRoI
Class for storing the 32-bit muon RoI word.
Definition: MuCTPIRoI.h:39
ROIB::CTPResult
Class holding the LVL1 CTP result used by the RoIBuilder.
Definition: Trigger/TrigT1/TrigT1Result/TrigT1Result/CTPResult.h:52
ROIB::JetEnergyRoI
Definition: JetEnergyRoI.h:20
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounceArray
void renounceArray(SG::VarHandleKeyArray &handlesArray)
remove all handles from I/O resolution
Definition: AthCommonDataStore.h:364
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
ROIB::CTPResult::dump
const std::string dump() const
dump raw object content to string
Definition: CTPResult.cxx:56
ROIB
Namespace of the LVL1 RoIB simulation.
Definition: ILvl1ResultAccessTool.h:19
ROIB::JetEnergyResult
Definition: JetEnergyResult.h:24
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
ROIB::RoIBuilder::m_caloEMTauLocation
SG::ReadHandleKeyArray< SlinkWordDV > m_caloEMTauLocation
Definition: RoIBuilder.h:57
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
ROIB::RoIBuilder::m_roibRDOLocation
SG::WriteHandleKey< RoIBResult > m_roibRDOLocation
Definition: RoIBuilder.h:73
histSizes.code
code
Definition: histSizes.py:129
lumiFormat.i
int i
Definition: lumiFormat.py:85
ROIB::MuCTPIRoI::roIWord
uint32_t roIWord() const
Method returning the RoI word.
Definition: MuCTPIRoI.cxx:35
ROIB::Header
Header models the LVL1 ROD Header.
Definition: TrigT1Result/TrigT1Result/Header.h:37
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
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
ROIB::EMTauRoI::roIWord
uint32_t roIWord() const
Definition: EMTauRoI.cxx:32
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
ROIB::RoIBuilder::m_muctpiSLinkLocation
SG::ReadHandleKey< L1MUINT::MuCTPIToRoIBSLink > m_muctpiSLinkLocation
Definition: RoIBuilder.h:69
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ROIB::JetEnergyRoI::roIWord
uint32_t roIWord() const
Method returning the RoI word.
Definition: JetEnergyRoI.cxx:32
ROIB::MuCTPIResult
Class holding the RoIs from the MuCTPI collected by the RoIB.
Definition: MuCTPIResult.h:44
ROIB::RoIBuilder::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: RoIBuilder.cxx:72
errorcheck.h
Helpers for checking error return status codes and reporting errors.
ROIB::Trailer
ROIB::Trailer models the LVL1 ROD Trailer.
Definition: Trailer.h:37
ROIB::RoIBuilder::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: RoIBuilder.h:55
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
ROIB::EMTauRoI
Definition: EMTauRoI.h:20
ROIB::RoIBuilder::m_doCalo
Gaudi::Property< bool > m_doCalo
Definition: RoIBuilder.h:46
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
PixelByteStreamErrors::Trailer
@ Trailer
Definition: PixelByteStreamErrors.h:13
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
TrigT1CTPDefs.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37