ATLAS Offline Software
Loading...
Searching...
No Matches
RoIBResultByteStreamTool.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// Local includes:
7
8// Trigger includes:
9#include "CTPfragment/CTPdataformat.h"
10#include "CTPfragment/CTPfragment.h"
11#include "L1TopoRDO/Helpers.h"
12#include "L1TopoRDO/L1TopoRDO.h"
15
16
17// TDAQ includes:
18#include "eformat/SourceIdentifier.h"
19
20// System includes
21#include <exception>
22#include <sstream>
23#include <span>
24
27
32RoIBResultByteStreamTool::RoIBResultByteStreamTool( const std::string& type, const std::string& name,
33 const IInterface* parent )
34 : base_class(type, name, parent) {}
35
42 ATH_MSG_DEBUG("Initialising RoIBResultByteStreamTool");
43
44 ConversionMode mode = getConversionMode(m_roibResultReadKey, m_roibResultWriteKey, msg());
45 ATH_CHECK(mode!=ConversionMode::Undefined);
46
47 // Set flags enabling/disabling each system
48 m_doCTP = (m_ctpModuleID != 0xFF);
49 m_doMuon = (m_muCTPIModuleID != 0xFF);
51 m_doEMTau = !m_emModuleID.empty();
52 m_doTopo = !m_l1TopoModuleID.empty();
53
54 if (msgLvl(MSG::DEBUG)) {
55 std::string_view modeName {(mode==ConversionMode::Encoding) ? "encoding" : "decoding"};
56 auto enabledStr = [](bool v) constexpr {return std::string_view(v ? "enabled" : "disabled");};
57 ATH_MSG_DEBUG("CTP " << modeName << " is " << enabledStr(m_doCTP));
58 ATH_MSG_DEBUG("MUCTPI " << modeName << " is " << enabledStr(m_doMuon));
59 ATH_MSG_DEBUG("Jet/Energy " << modeName << " is " << enabledStr(m_doJetEnergy));
60 ATH_MSG_DEBUG("EMTau " << modeName << " is " << enabledStr(m_doEMTau));
61 ATH_MSG_DEBUG("L1Topo " << modeName << " is " << enabledStr(m_doTopo));
62 }
63
64 // Initialise data handles
65 ATH_CHECK(m_roibResultWriteKey.initialize(mode==ConversionMode::Decoding));
66 ATH_CHECK(m_roibResultReadKey.initialize(mode==ConversionMode::Encoding));
67
68 // Set configured ROB IDs from module IDs
69 std::vector<eformat::helper::SourceIdentifier> configuredROBSIDs;
70 std::ostringstream str;
71 ATH_MSG_DEBUG("Configured module IDs for:");
72
73 // CTP
74 if (m_doCTP) {
75 configuredROBSIDs.emplace_back(eformat::TDAQ_CTP, m_ctpModuleID);
76 ATH_MSG_DEBUG(" CTP = 0x" << MSG::hex << m_ctpModuleID.value() << MSG::dec);
77 }
78
79 // MUCTPI
80 if (m_doMuon) {
81 configuredROBSIDs.emplace_back(eformat::TDAQ_MUON_CTP_INTERFACE, m_muCTPIModuleID);
82 ATH_MSG_DEBUG(" muCTPi = 0x" << MSG::hex << m_muCTPIModuleID.value() << MSG::dec);
83 }
84
85 // Jet/Energy
86 if (m_doJetEnergy) {
87 str.str("");
88 for (const uint16_t module_id : m_jetModuleID) {
89 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_JET_PROC_ROI, module_id);
90 str << "0x" << std::hex << module_id << std::dec << " ";
91 }
92 ATH_MSG_DEBUG(" Calorimeter Jet/Energy Processor RoI = " << str.str());
93 }
94
95 // EM/Tau
96 if (m_doEMTau) {
97 str.str("");
98 for (const uint16_t module_id : m_emModuleID) {
99 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_CLUSTER_PROC_ROI, module_id);
100 str << "0x" << std::hex << module_id << std::dec << " ";
101 }
102 ATH_MSG_DEBUG(" Calorimeter Cluster Processor RoI = " << str.str());
103 }
104
105 // L1Topo
106 if (m_doTopo) {
107 str.str("");
108 for (const uint16_t module_id : m_l1TopoModuleID) {
109 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_TOPO_PROC, module_id);
110 str << "0x" << std::hex << module_id << std::dec << " ";
111 }
112 ATH_MSG_DEBUG(" L1Topo = " << str.str());
113 }
114
115 // Fill the ROB ID vector
116 for (const auto& sid : configuredROBSIDs) {
117 m_configuredROBIds.push_back( sid.code() );
118 }
119
120 // Retrieve the ByteStreamCnvSvc for updating event header when writing CTP data to BS
121 if (m_doCTP && mode==ConversionMode::Encoding) {
122 m_byteStreamEventAccess = serviceLocator()->service("ByteStreamCnvSvc");
124 }
125
126 return StatusCode::SUCCESS;
127}
128
129StatusCode RoIBResultByteStreamTool::convertToBS(std::vector<OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment*>& vrobf,
130 const xAOD::TrigCompositeContainer* /*tc*/,
131 const EventContext& eventContext) {
132 auto roibResult = SG::makeHandle(m_roibResultReadKey, eventContext);
133 ATH_CHECK(roibResult.isValid());
134 ATH_MSG_DEBUG("Obtained ROIB::RoIBResult with key " << m_roibResultReadKey.key() << " for conversion to ByteStream");
135
136 auto addRob = [&](const eformat::helper::SourceIdentifier& sid, const size_t ndata, const uint32_t* data){
137 vrobf.push_back(newRobFragment(eventContext, sid.code(), ndata, data, m_detEvType));
138 return vrobf.back();
139 };
140 auto convertDataToRob = [&](const eformat::helper::SourceIdentifier& sid, const auto& dataVec){
141 uint32_t* data = newRodData(eventContext, dataVec.size());
142 ATH_MSG_VERBOSE("Dumping words for " << sid.human());
143 for (size_t i=0; i<dataVec.size(); ++i) {
144 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setw(8) << dataVec.at(i).roIWord() << MSG::dec);
145 data[i] = dataVec.at(i).roIWord();
146 }
147 return addRob(sid, dataVec.size(), data);
148 };
149
150 // CTP
151 if (m_doCTP) {
152 const eformat::helper::SourceIdentifier ctpSID{eformat::TDAQ_CTP, m_ctpModuleID};
153 const std::vector<ROIB::CTPRoI>& ctpDataVec = roibResult->cTPResult().roIVec();
154 OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment* rob = convertDataToRob(ctpSID, ctpDataVec);
155
156 // Update ROD minor version which encodes extra information about CTP data format (e.g. number of extra words)
157 rob->rod_minor_version(roibResult->cTPResult().header().formatVersion() & 0xffffu);
158
159 // Update L1 bits in event header
160 // TODO: change to context-aware method when it is added to the IByteStreamEventAccess interface
161 RawEventWrite* rawEvent = m_byteStreamEventAccess->getRawEvent();
162 std::bitset<512> tbp = ROIB::convertToBitset(roibResult->cTPResult().TBP());
163 std::bitset<512> tap = ROIB::convertToBitset(roibResult->cTPResult().TAP());
164 std::bitset<512> tav = ROIB::convertToBitset(roibResult->cTPResult().TAV());
165 constexpr size_t word_size = 32; // ATLAS raw event format word size
166 constexpr size_t words_per_set = 512 / word_size; // 512 CTP bits / word size
167 constexpr size_t num_words = 3 * words_per_set; // 3 sets: TBP, TAP, TAV
168 uint32_t* l1bits_data = newRodData(eventContext, num_words);
169 size_t iset{0};
170 for (const std::bitset<512>& bset : {tbp, tap, tav}) {
171 const std::string sbits = bset.to_string();
172 const size_t iword_output_start = words_per_set * iset;
173 for (size_t iword_in_set = 0; iword_in_set < words_per_set; ++iword_in_set) {
174 const size_t bword_pos = 512 - (iword_in_set+1) * word_size;
175 std::bitset<word_size> bword{sbits.substr(bword_pos, word_size)};
176 l1bits_data[iword_output_start + iword_in_set] = static_cast<uint32_t>(bword.to_ulong());
177 }
178 ++iset;
179 }
180 rawEvent->lvl1_trigger_info(num_words, l1bits_data);
181
182 // Update L1 TriggerType in event header
183 const uint32_t triggerType = roibResult->cTPResult().header().triggerType();
184 rawEvent->lvl1_trigger_type(static_cast<uint8_t>(triggerType & 0xFF));
185 }
186
187 // Muon
188 if (m_doMuon) {
189 const eformat::helper::SourceIdentifier muctpiSID{eformat::TDAQ_MUON_CTP_INTERFACE, m_muCTPIModuleID};
190 const std::vector<ROIB::MuCTPIRoI>& muctpiDataVec = roibResult->muCTPIResult().roIVec();
191 convertDataToRob(muctpiSID, muctpiDataVec);
192 }
193
194 // Jet/Energy
195 if (m_doJetEnergy) {
196 const std::vector<ROIB::JetEnergyResult>& jetEnergyResultVec = roibResult->jetEnergyResult();
197 for (size_t slink=0; slink<jetEnergyResultVec.size(); ++slink) {
198 const eformat::helper::SourceIdentifier jetSID{eformat::TDAQ_CALO_JET_PROC_ROI, m_jetModuleID.value().at(slink)};
199 convertDataToRob(jetSID, jetEnergyResultVec.at(slink).roIVec());
200 }
201 }
202
203 // EMTau
204 if (m_doEMTau) {
205 const std::vector<ROIB::EMTauResult>& emTauResultVec = roibResult->eMTauResult();
206 for (size_t slink=0; slink<emTauResultVec.size(); ++slink) {
207 const eformat::helper::SourceIdentifier emSID{eformat::TDAQ_CALO_CLUSTER_PROC_ROI, m_emModuleID.value().at(slink)};
208 convertDataToRob(emSID, emTauResultVec.at(slink).roIVec());
209 }
210 }
211
212 // L1Topo (slightly different interface from the others)
213 if (m_doTopo) {
214 const std::vector<ROIB::L1TopoResult>& l1TopoResultVec = roibResult->l1TopoResult();
215 for (size_t slink=0; slink<l1TopoResultVec.size(); ++slink) {
216 eformat::helper::SourceIdentifier topoSID{l1TopoResultVec.at(slink).rdo().getSourceID()};
217 ATH_MSG_VERBOSE("L1Topo source ID from RDO " << L1Topo::formatHex8(topoSID.code()));
218 if (topoSID.code() == 0 && slink < m_l1TopoModuleID.size()) {
219 topoSID = eformat::helper::SourceIdentifier(eformat::TDAQ_CALO_TOPO_PROC, m_l1TopoModuleID.value().at(slink));
220 ATH_MSG_DEBUG("Source ID in L1TopoRDO was zero so using Property for slink " << slink << ": "
221 << L1Topo::formatHex8(topoSID.code()));
222 }
223 else if (topoSID.code() == 0) {
224 topoSID = eformat::helper::SourceIdentifier( eformat::TDAQ_CALO_TOPO_PROC, 0 );
225 ATH_MSG_WARNING("Source ID in L1TopoRDO was zero, no properties available for slink counter " << slink
226 << ", so as a fall back, constructed module 0 with source ID "
227 << L1Topo::formatHex8(topoSID.code()));
228 }
229 const std::vector<uint32_t>& dataVec = l1TopoResultVec.at(slink).rdo().getDataWords();
230 uint32_t* data = newRodData(eventContext, dataVec.size());
231 for (size_t i=0; i<dataVec.size(); ++i) {
232 ATH_MSG_VERBOSE(" " << MSG::hex << std::setw(8) << std::showbase << dataVec.at(i) << std::noshowbase << MSG::dec);
233 data[i] = dataVec.at(i);
234 }
235 addRob(topoSID, dataVec.size(), data);
236 }
237 }
238
239 return StatusCode::SUCCESS;
240}
241
242StatusCode RoIBResultByteStreamTool::convertFromBS(const std::vector<const ROBFragment*>& vrobf,
243 const EventContext& eventContext) const {
244
245 if (m_roibResultWriteKey.empty()) {
246 ATH_MSG_ERROR("Conversion from BS to xAOD RoI requested but RoI WriteHandleKey is empty");
247 return StatusCode::FAILURE;
248 }
249 // Create all RDOs
250 ROIB::CTPResult cTPResult;
251 ROIB::MuCTPIResult muCTPIResult;
252 std::vector< ROIB::JetEnergyResult > jetEnergyResult(2);
253 std::vector< ROIB::EMTauResult > eMTauResult(4);
254 std::vector< ROIB::L1TopoResult > l1TopoResult;
255
256 // Create flags indicating whether or not ROB fragment was found
257 bool cTPFound = false;
258 bool muCTPIFound = false;
259 bool jetEnergyFound[2] = {false, false};
260 bool eMTauFound[4] = {false, false, false, false};
261 bool l1TopoFound = false;
262
263 // Loop over ROB fragments
264 for (const ROBFragment* p_robf : vrobf) {
265 const ROBFragment& robf = *p_robf;
266 eformat::helper::SourceIdentifier rodSID(robf.rod_source_id());
267 eformat::SubDetector rodSubdetId = rodSID.subdetector_id();
268 uint16_t rodModuleId = rodSID.module_id();
269
270 switch (rodSubdetId) {
271 // -----------------------------------------------------------------------
272 // CTP
273 // -----------------------------------------------------------------------
274 case eformat::TDAQ_CTP: {
275 if (!m_doCTP) continue;
276
277 // Check if the current ROD module ID matches the configured CTP module ID.
278 // Accept also ctpModuleId=0 to catch the early data with the old CTP firmware, which assigns 0x770000 to both
279 // DAQ and LVL2 ROD fragment - for this data we readout always multiple bunches for the DAQ ROD, therefore
280 // rodFragSize=46 should identify the LVL2 ROD fragment
281 if (rodModuleId != m_ctpModuleID && rodModuleId != 0) continue;
282 if (rodModuleId == 0 && robf.rod_fragment_size_word() != 46) continue;
283
284 // Flag as found
285 cTPFound = true;
286 ATH_MSG_DEBUG(" Found CTP ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
287
288 // Extract the data
289 DataStatus status;
290 ROIB::Header header = roibHeader(robf, status);
291 std::vector<ROIB::CTPRoI> content = roibContent<ROIB::CTPRoI>(robf);
292 ROIB::Trailer trailer = roibTrailer(status, content.size());
293
294 // Extract the CTP version number
295 const uint32_t* rod;
296 robf.rod_start(rod);
297 unsigned int ctpVersionNumber = ((rod[CTPdataformat::Helper::FormatVersionPos] >> CTPdataformat::CTPFormatVersionShift) & CTPdataformat::CTPFormatVersionMask);
298
299 // Create CTPResult object
300 cTPResult = ROIB::CTPResult(ctpVersionNumber, std::move(header), std::move(trailer), std::move(content));
301 break;
302 }
303
304 // -----------------------------------------------------------------------
305 // MUCTPI
306 // -----------------------------------------------------------------------
307 case eformat::TDAQ_MUON_CTP_INTERFACE: {
308 if (!m_doMuon) continue;
309
310 // Check if the current ROD module ID matches the configured MuCTPI module ID
311 if (rodModuleId != m_muCTPIModuleID) continue;
312
313 // Flag as found
314 muCTPIFound = true;
315 ATH_MSG_DEBUG(" Found MuCTPI ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
316
317 // Extract the data
318 DataStatus status;
319 ROIB::Header header = roibHeader(robf, status);
320 std::vector<ROIB::MuCTPIRoI> content = roibContent<ROIB::MuCTPIRoI>(robf);
321 ROIB::Trailer trailer = roibTrailer(status, content.size());
322
323 // Create MuCTPIResult object
324 muCTPIResult = ROIB::MuCTPIResult(std::move(header), std::move(trailer), std::move(content));
325 break;
326 }
327
328 // -----------------------------------------------------------------------
329 // Jet/Energy
330 // -----------------------------------------------------------------------
331 case eformat::TDAQ_CALO_JET_PROC_ROI: {
332 if (!m_doJetEnergy) continue;
333
334 // Check if the current ROD module ID matches the configured Jet/Energy module IDs
335 auto it = std::find(m_jetModuleID.begin(), m_jetModuleID.end(), rodModuleId);
336 if (it == m_jetModuleID.end()) continue;
337 size_t index = static_cast<size_t>(std::distance(m_jetModuleID.begin(), it));
338
339 // Flag as found
340 jetEnergyFound[index] = true;
341 ATH_MSG_DEBUG(" Found Jet/Energy ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
342
343 // Extract the data
344 DataStatus status;
345 ROIB::Header header = roibHeader(robf, status);
346 std::vector<ROIB::JetEnergyRoI> content = roibContent<ROIB::JetEnergyRoI>(robf);
347 ROIB::Trailer trailer = roibTrailer(status, content.size());
348
349 // Create JetEnergyResult object
350 jetEnergyResult[index] = ROIB::JetEnergyResult(std::move(header), std::move(trailer), std::move(content));
351 break;
352 }
353
354 // -----------------------------------------------------------------------
355 // EM/Tau
356 // -----------------------------------------------------------------------
357 case eformat::TDAQ_CALO_CLUSTER_PROC_ROI: {
358 if (!m_doEMTau) continue;
359
360 // Check if the current ROD module ID matches the configured EM/Tau module IDs
361 auto it = std::find(m_emModuleID.begin(), m_emModuleID.end(), rodModuleId);
362 if (it == m_emModuleID.end()) continue;
363 size_t index = static_cast<size_t>(std::distance(m_emModuleID.begin(), it));
364
365 // Flag as found
366 eMTauFound[index] = true;
367 ATH_MSG_DEBUG(" Found EM/Tau ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
368
369 // Extract the data
370 DataStatus status;
371 ROIB::Header header = roibHeader(robf, status);
372 std::vector<ROIB::EMTauRoI> content = roibContent<ROIB::EMTauRoI>(robf);
373 ROIB::Trailer trailer = roibTrailer(status, content.size());
374
375 // Create EMTauResult object
376 eMTauResult[index] = ROIB::EMTauResult(std::move(header), std::move(trailer), std::move(content));
377 break;
378 }
379
380 // -----------------------------------------------------------------------
381 // L1Topo
382 // -----------------------------------------------------------------------
383 case eformat::TDAQ_CALO_TOPO_PROC: {
384 if (!m_doTopo) continue;
385
386 // Check if the current ROD module ID matches the configured L1Topo module IDs
387 auto it = std::find(m_l1TopoModuleID.begin(), m_l1TopoModuleID.end(), rodModuleId);
388 if (it == m_l1TopoModuleID.end()) continue;
389
390 // Flag as found
391 l1TopoFound = true;
392 ATH_MSG_DEBUG(" Found L1Topo ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
393
394 // Extract the data
395 DataStatus status;
396 ROIB::Header header = roibHeader(robf, status);
397 L1TopoRDO content = l1topoContent(robf);
398 ROIB::Trailer trailer = roibTrailer(status, content.getDataWords().size());
399
400 // Set status words
401 content.setStatusWords({status.status_word, status.status_info});
402
403 // Flag errors in RDO
404 if (status.status_word != 0) content.setError(L1Topo::Error::SLINK_STATUS_ERROR);
405 if (status.rob_error) content.setError(L1Topo::Error::ROB_ERROR);
406 if (status.rod_error) content.setError(L1Topo::Error::ROD_ERROR);
407
408 // Create L1TopoResult object
409 l1TopoResult.emplace_back(std::move(header), std::move(trailer), std::move(content));
410 break;
411 }
412
413 default: {
414 ATH_MSG_DEBUG("Skipping ROD with SubDetID " << rodSID.human_detector());
415 break;
416 }
417 }
418
419 } // End of loop over all ROB fragments
420
421 ATH_MSG_DEBUG("Building RoIBResult with the following inputs:");
422 ATH_MSG_DEBUG(" CTP - " << (cTPFound ? "found" : "not found"));
423 ATH_MSG_DEBUG(" MUCTPI - " << (muCTPIFound ? "found" : "not found"));
424 ATH_MSG_DEBUG(" Jet/Energy[0/1] - " << (jetEnergyFound[0] ? "found" : "not found") << "/"
425 << (jetEnergyFound[1] ? "found" : "not found"));
426 ATH_MSG_DEBUG(" EM/Tau[0/1/2/3] - " << (eMTauFound[0] ? "found" : "not found") << "/"
427 << (eMTauFound[1] ? "found" : "not found") << "/"
428 << (eMTauFound[2] ? "found" : "not found") << "/"
429 << (eMTauFound[3] ? "found" : "not found"));
430 ATH_MSG_DEBUG(" L1Topo - " << (l1TopoFound ? "found" : "not found"));
431
432
433 // Create and record the RoIBResult
434 auto roibResult = SG::makeHandle(m_roibResultWriteKey, eventContext);
435 ATH_CHECK(roibResult.record(std::make_unique<ROIB::RoIBResult>(std::move(muCTPIResult), std::move(cTPResult), std::move(jetEnergyResult), std::move(eMTauResult))));
436 ATH_MSG_DEBUG("Recorded RoIBResult with key " << m_roibResultWriteKey.key());
437
438 // Add L1Topo result
439 if (l1TopoFound) roibResult->l1TopoResult(std::move(l1TopoResult));
440
441 return StatusCode::SUCCESS;
442}
443
445 DataStatus& dataStatus) const {
446 // Get format version and event number of fragment
447 uint32_t formatVersion = rob.rod_version();
448 uint32_t evtNum = rob.rod_lvl1_id();
449 uint32_t robFragSize = rob.fragment_size_word();
450 uint32_t rodFragSize = rob.rod_fragment_size_word();
451 uint32_t robId = rob.source_id();
452 uint32_t rodId = rob.rod_source_id();
453
454 // Check for errors
455 dataStatus.rob_error = false;
456 dataStatus.rod_error = false;
457 dataStatus.status_word = 0;
458 dataStatus.status_info = 0;
459
460 try {
461 if (rob.check_rob()) ATH_MSG_VERBOSE("ROB fragment checked ok");
462 }
463 catch (std::exception const & ex) {
464 ATH_MSG_WARNING("ROB fragment not valid: " << ex.what());
465 dataStatus.rob_error = true;
466 }
467
468 try {
469 if (rob.check_rod()) ATH_MSG_VERBOSE("ROD fragment checked ok");
470 }
471 catch (std::exception const & ex) {
472 ATH_MSG_WARNING("ROD fragment not valid: " << ex.what());
473 dataStatus.rod_error = true;
474 }
475
476 // Process the status words
477 DataType status;
478 rob.rod_status(status);
479 uint32_t nstatus = rob.rod_nstatus();
480 ATH_MSG_VERBOSE("Number of status words: " << nstatus);
481 if (msgLvl(MSG::VERBOSE)) {
482 for (uint32_t i=0; i<nstatus; ++i, ++status) {
483 ATH_MSG_VERBOSE(" Status word: 0x" << MSG::hex << std::setw(8) << std::setfill('0') << *status);
484 }
485 }
486 rob.rod_status(status);
487
488 if(nstatus > 0) dataStatus.status_word = static_cast<uint32_t>(*status);
489 if(nstatus > 1) {
490 ++status;
491 dataStatus.status_info = static_cast<uint32_t>(*status);
492 }
493
494 ATH_MSG_DEBUG("ROB ID 0x" << MSG::hex << robId << " ROD ID 0x" << rodId << MSG::dec << " ROB fragment size "
495 << robFragSize << " ROD fragment size " << rodFragSize);
496
497 return ROIB::Header(rodId, evtNum, formatVersion);
498}
499
500ROIB::Trailer RoIBResultByteStreamTool::roibTrailer(const DataStatus& dataStatus, uint32_t dataSize) const {
501 std::vector<uint32_t> words;
502 words.reserve(5);
503 words.push_back(dataStatus.status_word); // error status
504 words.push_back(dataStatus.status_info); // status info
505 words.push_back(2); // number of status words
506 words.push_back(dataSize); // number of data words
507 words.push_back(1); // status block position
508 return ROIB::Trailer(std::move(words));
509}
510
511template<typename RoIType> std::vector<RoIType> RoIBResultByteStreamTool::roibContent(const ROBFragment& rob) const {
512 uint32_t ndata = rob.rod_ndata();
514 rob.rod_data(data);
515 std::vector<RoIType> content;
516 content.reserve(ndata);
517 ATH_MSG_VERBOSE(" Dumping RoI Words:");
518 for (const uint32_t word : std::span{data, ndata}) {
519 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8) << word << MSG::dec);
520 content.push_back(RoIType{word});
521 }
522 return content;
523}
524
526 uint32_t ndata = rob.rod_ndata();
528 rob.rod_data(data);
529 L1TopoRDO content;
530 ATH_MSG_VERBOSE( " Dumping RoI Words:" );
531 std::vector<uint32_t> vDataWords;
532 vDataWords.reserve(ndata);
533 for (const uint32_t word : std::span{data, ndata}) {
534 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8) << word << MSG::dec);
535 vDataWords.push_back(word);
536 }
537 content.setDataWords(std::move(vDataWords));
538 content.setSourceID(rob.rod_source_id());
539 return content;
540}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition RawEvent.h:39
#define sbits(u, n)
Intrinsic functions which do not work correctly due to differences in byte ordering.
The class that represents the raw data received from an L1Topo board.
Definition L1TopoRDO.h:29
Class holding the LVL1 CTP result used by the RoIBuilder.
Header models the LVL1 ROD Header.
Class holding the RoIs from the MuCTPI collected by the RoIB.
ROIB::Trailer models the LVL1 ROD Trailer.
Definition Trailer.h:37
Gaudi::Property< std::vector< uint16_t > > m_l1TopoModuleID
L1Topo Module IDs to decode.
Gaudi::Property< uint16_t > m_muCTPIModuleID
MUCTPI Module ID to decode.
ROIB::Trailer roibTrailer(const DataStatus &dataStatus, const uint32_t dataSize) const
Helper method to extract ROD trailer information @in dataStatus Structure to flag data errors (extrac...
virtual StatusCode convertFromBS(const std::vector< const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment * > &vrobf, const EventContext &eventContext) const override
Convert ROB fragments to RoIBResult.
ROIB::Header roibHeader(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &rob, DataStatus &dataStatus) const
Helper method to extract ROD header information @in rob ROBFragment from which data are extracted @ou...
Gaudi::Property< uint16_t > m_ctpModuleID
RoIBResultByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
L1TopoRDO l1topoContent(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &rob) const
Helper method to extract ROD payload for L1Topo (different interface from other RoI data) @in ndata N...
Gaudi::Property< uint16_t > m_detEvType
Detector event type to write when converting to ByteStream.
virtual StatusCode initialize() override
Function to initialise the tool.
std::vector< uint32_t > m_configuredROBIds
Vector of ROB IDs corresponding to the modules configured for decoding.
Gaudi::Property< std::vector< uint16_t > > m_emModuleID
EM Module IDs to decode.
SG::WriteHandleKey< ROIB::RoIBResult > m_roibResultWriteKey
SmartIF< IByteStreamEventAccess > m_byteStreamEventAccess
Interface to get raw event pointer for updating event header when writing to BS.
std::vector< RoIType > roibContent(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &rob) const
Helper method to extract ROD payload @in ndata Number of data words @in data Data words.
SG::ReadHandleKey< ROIB::RoIBResult > m_roibResultReadKey
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const xAOD::TrigCompositeContainer *tc, const EventContext &eventContext) override
Convert RoIBResult to ByteStream.
Gaudi::Property< std::vector< uint16_t > > m_jetModuleID
Jet Module IDs to decode.
std::string formatHex8(uint32_t word)
Helper function to format a 32-bit integer as an 8-digit hex number for printing.
@ SLINK_STATUS_ERROR
Definition Error.h:16
eformat::write::ROBFragment ROBFragment
Definition RawEvent.h:33
const DataType * PointerType
Definition RawEvent.h:25
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27
std::bitset< 512 > convertToBitset(const std::vector< uint32_t > &words)
convert vector of unsigned int into bitset
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
Structure holding the status words and rob/rod error flags.
MsgStream & msg
Definition testRead.cxx:32