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 EventContext& eventContext) {
131 auto roibResult = SG::makeHandle(m_roibResultReadKey, eventContext);
132 ATH_CHECK(roibResult.isValid());
133 ATH_MSG_DEBUG("Obtained ROIB::RoIBResult with key " << m_roibResultReadKey.key() << " for conversion to ByteStream");
134
135 auto addRob = [&](const eformat::helper::SourceIdentifier& sid, const size_t ndata, const uint32_t* data){
136 vrobf.push_back(newRobFragment(eventContext, sid.code(), ndata, data, m_detEvType));
137 return vrobf.back();
138 };
139 auto convertDataToRob = [&](const eformat::helper::SourceIdentifier& sid, const auto& dataVec){
140 uint32_t* data = newRodData(eventContext, dataVec.size());
141 ATH_MSG_VERBOSE("Dumping words for " << sid.human());
142 for (size_t i=0; i<dataVec.size(); ++i) {
143 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setw(8) << dataVec.at(i).roIWord() << MSG::dec);
144 data[i] = dataVec.at(i).roIWord();
145 }
146 return addRob(sid, dataVec.size(), data);
147 };
148
149 // CTP
150 if (m_doCTP) {
151 const eformat::helper::SourceIdentifier ctpSID{eformat::TDAQ_CTP, m_ctpModuleID};
152 const std::vector<ROIB::CTPRoI>& ctpDataVec = roibResult->cTPResult().roIVec();
153 OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment* rob = convertDataToRob(ctpSID, ctpDataVec);
154
155 // Update ROD minor version which encodes extra information about CTP data format (e.g. number of extra words)
156 rob->rod_minor_version(roibResult->cTPResult().header().formatVersion() & 0xffffu);
157
158 // Update L1 bits in event header
159 // TODO: change to context-aware method when it is added to the IByteStreamEventAccess interface
160 RawEventWrite* rawEvent = m_byteStreamEventAccess->getRawEvent();
161 std::bitset<512> tbp = ROIB::convertToBitset(roibResult->cTPResult().TBP());
162 std::bitset<512> tap = ROIB::convertToBitset(roibResult->cTPResult().TAP());
163 std::bitset<512> tav = ROIB::convertToBitset(roibResult->cTPResult().TAV());
164 constexpr size_t word_size = 32; // ATLAS raw event format word size
165 constexpr size_t words_per_set = 512 / word_size; // 512 CTP bits / word size
166 constexpr size_t num_words = 3 * words_per_set; // 3 sets: TBP, TAP, TAV
167 uint32_t* l1bits_data = newRodData(eventContext, num_words);
168 size_t iset{0};
169 for (const std::bitset<512>& bset : {tbp, tap, tav}) {
170 const std::string sbits = bset.to_string();
171 const size_t iword_output_start = words_per_set * iset;
172 for (size_t iword_in_set = 0; iword_in_set < words_per_set; ++iword_in_set) {
173 const size_t bword_pos = 512 - (iword_in_set+1) * word_size;
174 std::bitset<word_size> bword{sbits.substr(bword_pos, word_size)};
175 l1bits_data[iword_output_start + iword_in_set] = static_cast<uint32_t>(bword.to_ulong());
176 }
177 ++iset;
178 }
179 rawEvent->lvl1_trigger_info(num_words, l1bits_data);
180
181 // Update L1 TriggerType in event header
182 const uint32_t triggerType = roibResult->cTPResult().header().triggerType();
183 rawEvent->lvl1_trigger_type(static_cast<uint8_t>(triggerType & 0xFF));
184 }
185
186 // Muon
187 if (m_doMuon) {
188 const eformat::helper::SourceIdentifier muctpiSID{eformat::TDAQ_MUON_CTP_INTERFACE, m_muCTPIModuleID};
189 const std::vector<ROIB::MuCTPIRoI>& muctpiDataVec = roibResult->muCTPIResult().roIVec();
190 convertDataToRob(muctpiSID, muctpiDataVec);
191 }
192
193 // Jet/Energy
194 if (m_doJetEnergy) {
195 const std::vector<ROIB::JetEnergyResult>& jetEnergyResultVec = roibResult->jetEnergyResult();
196 for (size_t slink=0; slink<jetEnergyResultVec.size(); ++slink) {
197 const eformat::helper::SourceIdentifier jetSID{eformat::TDAQ_CALO_JET_PROC_ROI, m_jetModuleID.value().at(slink)};
198 convertDataToRob(jetSID, jetEnergyResultVec.at(slink).roIVec());
199 }
200 }
201
202 // EMTau
203 if (m_doEMTau) {
204 const std::vector<ROIB::EMTauResult>& emTauResultVec = roibResult->eMTauResult();
205 for (size_t slink=0; slink<emTauResultVec.size(); ++slink) {
206 const eformat::helper::SourceIdentifier emSID{eformat::TDAQ_CALO_CLUSTER_PROC_ROI, m_emModuleID.value().at(slink)};
207 convertDataToRob(emSID, emTauResultVec.at(slink).roIVec());
208 }
209 }
210
211 // L1Topo (slightly different interface from the others)
212 if (m_doTopo) {
213 const std::vector<ROIB::L1TopoResult>& l1TopoResultVec = roibResult->l1TopoResult();
214 for (size_t slink=0; slink<l1TopoResultVec.size(); ++slink) {
215 eformat::helper::SourceIdentifier topoSID{l1TopoResultVec.at(slink).rdo().getSourceID()};
216 ATH_MSG_VERBOSE("L1Topo source ID from RDO " << L1Topo::formatHex8(topoSID.code()));
217 if (topoSID.code() == 0 && slink < m_l1TopoModuleID.size()) {
218 topoSID = eformat::helper::SourceIdentifier(eformat::TDAQ_CALO_TOPO_PROC, m_l1TopoModuleID.value().at(slink));
219 ATH_MSG_DEBUG("Source ID in L1TopoRDO was zero so using Property for slink " << slink << ": "
220 << L1Topo::formatHex8(topoSID.code()));
221 }
222 else if (topoSID.code() == 0) {
223 topoSID = eformat::helper::SourceIdentifier( eformat::TDAQ_CALO_TOPO_PROC, 0 );
224 ATH_MSG_WARNING("Source ID in L1TopoRDO was zero, no properties available for slink counter " << slink
225 << ", so as a fall back, constructed module 0 with source ID "
226 << L1Topo::formatHex8(topoSID.code()));
227 }
228 const std::vector<uint32_t>& dataVec = l1TopoResultVec.at(slink).rdo().getDataWords();
229 uint32_t* data = newRodData(eventContext, dataVec.size());
230 for (size_t i=0; i<dataVec.size(); ++i) {
231 ATH_MSG_VERBOSE(" " << MSG::hex << std::setw(8) << std::showbase << dataVec.at(i) << std::noshowbase << MSG::dec);
232 data[i] = dataVec.at(i);
233 }
234 addRob(topoSID, dataVec.size(), data);
235 }
236 }
237
238 return StatusCode::SUCCESS;
239}
240
241StatusCode RoIBResultByteStreamTool::convertFromBS(const std::vector<const ROBFragment*>& vrobf,
242 const EventContext& eventContext) const {
243
244 if (m_roibResultWriteKey.empty()) {
245 ATH_MSG_ERROR("Conversion from BS to xAOD RoI requested but RoI WriteHandleKey is empty");
246 return StatusCode::FAILURE;
247 }
248 // Create all RDOs
249 ROIB::CTPResult cTPResult;
250 ROIB::MuCTPIResult muCTPIResult;
251 std::vector< ROIB::JetEnergyResult > jetEnergyResult(2);
252 std::vector< ROIB::EMTauResult > eMTauResult(4);
253 std::vector< ROIB::L1TopoResult > l1TopoResult;
254
255 // Create flags indicating whether or not ROB fragment was found
256 bool cTPFound = false;
257 bool muCTPIFound = false;
258 bool jetEnergyFound[2] = {false, false};
259 bool eMTauFound[4] = {false, false, false, false};
260 bool l1TopoFound = false;
261
262 // Loop over ROB fragments
263 for (const ROBFragment* p_robf : vrobf) {
264 const ROBFragment& robf = *p_robf;
265 eformat::helper::SourceIdentifier rodSID(robf.rod_source_id());
266 eformat::SubDetector rodSubdetId = rodSID.subdetector_id();
267 uint16_t rodModuleId = rodSID.module_id();
268
269 switch (rodSubdetId) {
270 // -----------------------------------------------------------------------
271 // CTP
272 // -----------------------------------------------------------------------
273 case eformat::TDAQ_CTP: {
274 if (!m_doCTP) continue;
275
276 // Check if the current ROD module ID matches the configured CTP module ID.
277 // Accept also ctpModuleId=0 to catch the early data with the old CTP firmware, which assigns 0x770000 to both
278 // DAQ and LVL2 ROD fragment - for this data we readout always multiple bunches for the DAQ ROD, therefore
279 // rodFragSize=46 should identify the LVL2 ROD fragment
280 if (rodModuleId != m_ctpModuleID && rodModuleId != 0) continue;
281 if (rodModuleId == 0 && robf.rod_fragment_size_word() != 46) continue;
282
283 // Flag as found
284 cTPFound = true;
285 ATH_MSG_DEBUG(" Found CTP ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
286
287 // Extract the data
288 DataStatus status;
289 ROIB::Header header = roibHeader(robf, status);
290 std::vector<ROIB::CTPRoI> content = roibContent<ROIB::CTPRoI>(robf);
291 ROIB::Trailer trailer = roibTrailer(status, content.size());
292
293 // Extract the CTP version number
294 const uint32_t* rod;
295 robf.rod_start(rod);
296 unsigned int ctpVersionNumber = ((rod[CTPdataformat::Helper::FormatVersionPos] >> CTPdataformat::CTPFormatVersionShift) & CTPdataformat::CTPFormatVersionMask);
297
298 // Create CTPResult object
299 cTPResult = ROIB::CTPResult(ctpVersionNumber, std::move(header), std::move(trailer), std::move(content));
300 break;
301 }
302
303 // -----------------------------------------------------------------------
304 // MUCTPI
305 // -----------------------------------------------------------------------
306 case eformat::TDAQ_MUON_CTP_INTERFACE: {
307 if (!m_doMuon) continue;
308
309 // Check if the current ROD module ID matches the configured MuCTPI module ID
310 if (rodModuleId != m_muCTPIModuleID) continue;
311
312 // Flag as found
313 muCTPIFound = true;
314 ATH_MSG_DEBUG(" Found MuCTPI ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
315
316 // Extract the data
317 DataStatus status;
318 ROIB::Header header = roibHeader(robf, status);
319 std::vector<ROIB::MuCTPIRoI> content = roibContent<ROIB::MuCTPIRoI>(robf);
320 ROIB::Trailer trailer = roibTrailer(status, content.size());
321
322 // Create MuCTPIResult object
323 muCTPIResult = ROIB::MuCTPIResult(std::move(header), std::move(trailer), std::move(content));
324 break;
325 }
326
327 // -----------------------------------------------------------------------
328 // Jet/Energy
329 // -----------------------------------------------------------------------
330 case eformat::TDAQ_CALO_JET_PROC_ROI: {
331 if (!m_doJetEnergy) continue;
332
333 // Check if the current ROD module ID matches the configured Jet/Energy module IDs
334 auto it = std::find(m_jetModuleID.begin(), m_jetModuleID.end(), rodModuleId);
335 if (it == m_jetModuleID.end()) continue;
336 size_t index = static_cast<size_t>(std::distance(m_jetModuleID.begin(), it));
337
338 // Flag as found
339 jetEnergyFound[index] = true;
340 ATH_MSG_DEBUG(" Found Jet/Energy ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
341
342 // Extract the data
343 DataStatus status;
344 ROIB::Header header = roibHeader(robf, status);
345 std::vector<ROIB::JetEnergyRoI> content = roibContent<ROIB::JetEnergyRoI>(robf);
346 ROIB::Trailer trailer = roibTrailer(status, content.size());
347
348 // Create JetEnergyResult object
349 jetEnergyResult[index] = ROIB::JetEnergyResult(std::move(header), std::move(trailer), std::move(content));
350 break;
351 }
352
353 // -----------------------------------------------------------------------
354 // EM/Tau
355 // -----------------------------------------------------------------------
356 case eformat::TDAQ_CALO_CLUSTER_PROC_ROI: {
357 if (!m_doEMTau) continue;
358
359 // Check if the current ROD module ID matches the configured EM/Tau module IDs
360 auto it = std::find(m_emModuleID.begin(), m_emModuleID.end(), rodModuleId);
361 if (it == m_emModuleID.end()) continue;
362 size_t index = static_cast<size_t>(std::distance(m_emModuleID.begin(), it));
363
364 // Flag as found
365 eMTauFound[index] = true;
366 ATH_MSG_DEBUG(" Found EM/Tau ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
367
368 // Extract the data
369 DataStatus status;
370 ROIB::Header header = roibHeader(robf, status);
371 std::vector<ROIB::EMTauRoI> content = roibContent<ROIB::EMTauRoI>(robf);
372 ROIB::Trailer trailer = roibTrailer(status, content.size());
373
374 // Create EMTauResult object
375 eMTauResult[index] = ROIB::EMTauResult(std::move(header), std::move(trailer), std::move(content));
376 break;
377 }
378
379 // -----------------------------------------------------------------------
380 // L1Topo
381 // -----------------------------------------------------------------------
382 case eformat::TDAQ_CALO_TOPO_PROC: {
383 if (!m_doTopo) continue;
384
385 // Check if the current ROD module ID matches the configured L1Topo module IDs
386 auto it = std::find(m_l1TopoModuleID.begin(), m_l1TopoModuleID.end(), rodModuleId);
387 if (it == m_l1TopoModuleID.end()) continue;
388
389 // Flag as found
390 l1TopoFound = true;
391 ATH_MSG_DEBUG(" Found L1Topo ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
392
393 // Extract the data
394 DataStatus status;
395 ROIB::Header header = roibHeader(robf, status);
396 L1TopoRDO content = l1topoContent(robf);
397 ROIB::Trailer trailer = roibTrailer(status, content.getDataWords().size());
398
399 // Set status words
400 content.setStatusWords({status.status_word, status.status_info});
401
402 // Flag errors in RDO
403 if (status.status_word != 0) content.setError(L1Topo::Error::SLINK_STATUS_ERROR);
404 if (status.rob_error) content.setError(L1Topo::Error::ROB_ERROR);
405 if (status.rod_error) content.setError(L1Topo::Error::ROD_ERROR);
406
407 // Create L1TopoResult object
408 l1TopoResult.emplace_back(std::move(header), std::move(trailer), std::move(content));
409 break;
410 }
411
412 default: {
413 ATH_MSG_DEBUG("Skipping ROD with SubDetID " << rodSID.human_detector());
414 break;
415 }
416 }
417
418 } // End of loop over all ROB fragments
419
420 ATH_MSG_DEBUG("Building RoIBResult with the following inputs:");
421 ATH_MSG_DEBUG(" CTP - " << (cTPFound ? "found" : "not found"));
422 ATH_MSG_DEBUG(" MUCTPI - " << (muCTPIFound ? "found" : "not found"));
423 ATH_MSG_DEBUG(" Jet/Energy[0/1] - " << (jetEnergyFound[0] ? "found" : "not found") << "/"
424 << (jetEnergyFound[1] ? "found" : "not found"));
425 ATH_MSG_DEBUG(" EM/Tau[0/1/2/3] - " << (eMTauFound[0] ? "found" : "not found") << "/"
426 << (eMTauFound[1] ? "found" : "not found") << "/"
427 << (eMTauFound[2] ? "found" : "not found") << "/"
428 << (eMTauFound[3] ? "found" : "not found"));
429 ATH_MSG_DEBUG(" L1Topo - " << (l1TopoFound ? "found" : "not found"));
430
431
432 // Create and record the RoIBResult
433 auto roibResult = SG::makeHandle(m_roibResultWriteKey, eventContext);
434 ATH_CHECK(roibResult.record(std::make_unique<ROIB::RoIBResult>(std::move(muCTPIResult), std::move(cTPResult), std::move(jetEnergyResult), std::move(eMTauResult))));
435 ATH_MSG_DEBUG("Recorded RoIBResult with key " << m_roibResultWriteKey.key());
436
437 // Add L1Topo result
438 if (l1TopoFound) roibResult->l1TopoResult(std::move(l1TopoResult));
439
440 return StatusCode::SUCCESS;
441}
442
444 DataStatus& dataStatus) const {
445 // Get format version and event number of fragment
446 uint32_t formatVersion = rob.rod_version();
447 uint32_t evtNum = rob.rod_lvl1_id();
448 uint32_t robFragSize = rob.fragment_size_word();
449 uint32_t rodFragSize = rob.rod_fragment_size_word();
450 uint32_t robId = rob.source_id();
451 uint32_t rodId = rob.rod_source_id();
452
453 // Check for errors
454 dataStatus.rob_error = false;
455 dataStatus.rod_error = false;
456 dataStatus.status_word = 0;
457 dataStatus.status_info = 0;
458
459 try {
460 if (rob.check_rob()) ATH_MSG_VERBOSE("ROB fragment checked ok");
461 }
462 catch (std::exception const & ex) {
463 ATH_MSG_WARNING("ROB fragment not valid: " << ex.what());
464 dataStatus.rob_error = true;
465 }
466
467 try {
468 if (rob.check_rod()) ATH_MSG_VERBOSE("ROD fragment checked ok");
469 }
470 catch (std::exception const & ex) {
471 ATH_MSG_WARNING("ROD fragment not valid: " << ex.what());
472 dataStatus.rod_error = true;
473 }
474
475 // Process the status words
476 DataType status;
477 rob.rod_status(status);
478 uint32_t nstatus = rob.rod_nstatus();
479 ATH_MSG_VERBOSE("Number of status words: " << nstatus);
480 if (msgLvl(MSG::VERBOSE)) {
481 for (uint32_t i=0; i<nstatus; ++i, ++status) {
482 ATH_MSG_VERBOSE(" Status word: 0x" << MSG::hex << std::setw(8) << std::setfill('0') << *status);
483 }
484 }
485 rob.rod_status(status);
486
487 if(nstatus > 0) dataStatus.status_word = static_cast<uint32_t>(*status);
488 if(nstatus > 1) {
489 ++status;
490 dataStatus.status_info = static_cast<uint32_t>(*status);
491 }
492
493 ATH_MSG_DEBUG("ROB ID 0x" << MSG::hex << robId << " ROD ID 0x" << rodId << MSG::dec << " ROB fragment size "
494 << robFragSize << " ROD fragment size " << rodFragSize);
495
496 return ROIB::Header(rodId, evtNum, formatVersion);
497}
498
499ROIB::Trailer RoIBResultByteStreamTool::roibTrailer(const DataStatus& dataStatus, uint32_t dataSize) const {
500 std::vector<uint32_t> words;
501 words.reserve(5);
502 words.push_back(dataStatus.status_word); // error status
503 words.push_back(dataStatus.status_info); // status info
504 words.push_back(2); // number of status words
505 words.push_back(dataSize); // number of data words
506 words.push_back(1); // status block position
507 return ROIB::Trailer(std::move(words));
508}
509
510template<typename RoIType> std::vector<RoIType> RoIBResultByteStreamTool::roibContent(const ROBFragment& rob) const {
511 uint32_t ndata = rob.rod_ndata();
513 rob.rod_data(data);
514 std::vector<RoIType> content;
515 content.reserve(ndata);
516 ATH_MSG_VERBOSE(" Dumping RoI Words:");
517 for (const uint32_t word : std::span{data, ndata}) {
518 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8) << word << MSG::dec);
519 content.push_back(RoIType{word});
520 }
521 return content;
522}
523
525 uint32_t ndata = rob.rod_ndata();
527 rob.rod_data(data);
528 L1TopoRDO content;
529 ATH_MSG_VERBOSE( " Dumping RoI Words:" );
530 std::vector<uint32_t> vDataWords;
531 vDataWords.reserve(ndata);
532 for (const uint32_t word : std::span{data, ndata}) {
533 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8) << word << MSG::dec);
534 vDataWords.push_back(word);
535 }
536 content.setDataWords(std::move(vDataWords));
537 content.setSourceID(rob.rod_source_id());
538 return content;
539}
#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.
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const EventContext &eventContext) override
Convert RoIBResult to ByteStream.
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
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
Structure holding the status words and rob/rod error flags.
MsgStream & msg
Definition testRead.cxx:32