ATLAS Offline Software
Loading...
Searching...
No Matches
L1TopoByteStreamTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <exception>
6#include <bitset>
7
8// Gaudi/Athena include(s):
10
11// Trigger include(s):
12#include "L1TopoRDO/L1TopoRDO.h"
14#include "L1TopoRDO/ModuleID.h"
15#include "L1TopoRDO/Helpers.h"
16
17// Local include(s):
19
21static const InterfaceID IID_IL1TopoByteStreamTool("L1TopoByteStreamTool", 1,
22 0);
23
31
37 const std::string& name,
38 const IInterface* parent)
39 : AthAlgTool(type, name, parent),
40 m_srcIdMap(0),
41 m_robDataProvider("ROBDataProviderSvc", "L1TopoByteStreamTool") {
42 declareInterface<L1TopoByteStreamTool>(this);
43 declareProperty("ROBSourceIDs", m_sourceIDs,
44 "ROB fragment source identifiers - overrides decodeDAQROBs "
45 "and decodeROIROBs");
47 "decodeDAQROBs", m_doDAQROBs = true,
48 "add standard DAQ ROBs to list of ROBs to decode; default true");
50 "decodeROIROBs", m_doROIROBs = false,
51 "add standard ROI ROBs to list of ROBs to decode; default false");
52}
53
58
66 if (!m_sourceIDs.empty()) {
68 "ROBSourceIDs property is set: this overrides decodeDAQROBs and "
69 "decodeROIROBs");
70 } else {
72 }
75 ATH_MSG_DEBUG("using sourceIDs " << std::hex << std::showbase << m_sourceIDs
76 << std::dec << std::noshowbase);
77
78 CHECK(m_robDataProvider.retrieve());
79 return AlgTool::initialize();
80}
81
86 delete m_srcIdMap;
87 return AlgTool::finalize();
88}
89
100const std::vector<uint32_t>& L1TopoByteStreamTool::sourceIDs() {
101 if (m_sourceIDs.empty()) {
102 // iterate over link numbers: 0 is DAQ link, 1 is ROIB, 2 for New ROIB
103 for (unsigned int slink : {0, 1, 2}) {
104 unsigned int roiOrDaq = 0;
105 if (slink > 0) { // 0 means DAQ-type link, 1 means ROI-type link
106 roiOrDaq = 1;
107 }
108 if (roiOrDaq == 0 && !m_doDAQROBs) {
109 continue; // skip DAQ ROBs
110 } else if (roiOrDaq == 1 && !m_doROIROBs) {
111 continue; // skip ROI ROBs
112 }
113 for (unsigned int module :
114 {0, 1}) { // could be upgraded to 3 modules eventually?
115 const uint32_t moduleId =
116 L1Topo::ModuleID(slink, module, roiOrDaq).id();
117 eformat::helper::SourceIdentifier sourceId(eformat::TDAQ_CALO_TOPO_PROC, moduleId);
118
119 m_sourceIDs.push_back(sourceId.code());
120 }
121 }
122 }
123 return m_sourceIDs;
124}
125
131 RawEventWrite* re) const{
132 ATH_MSG_DEBUG("executing convert() from RDO to ROBFragment");
133
134 // Create Event Assembler
136
137 // Reset lumi-block number to 1
138 fea.setDetEvtType(1);
139 // Set L1Apos to center of readout window
140 // uint16_t minorVersion = ( result->getNumberOfBunches() - 1u ) / 2u;
141 // minorVersion &= ctpVersion.getL1APositionMask();
142 // minorVersion <<= ctpVersion.getL1APositionShift();
143 uint16_t minorVersion = 0;
144 fea.setRodMinorVersion(minorVersion);
145
147
148 // Source ID of L1Topo
149 // NB needs to change to using list of modules - as it is, it will just
150 // produce one with an unconventional ID of 0x91000000.
151 const uint32_t rodId = m_srcIdMap->getRodID();
152 ATH_MSG_DEBUG(" ROD ID:" << MSG::hex << rodId);
153 ATH_MSG_DEBUG(" ROD IDs:" << MSG::hex << m_sourceIDs << " NOT YET IMPLEMENTED");
154
155 // get the ROD data container to be filled
156 theROD = fea.getRodData(rodId);
157
158 ATH_MSG_VERBOSE(" Dumping L1Topo data words:");
159 // fill Data Words
160 const std::vector<uint32_t>& vDataWords = result->getDataWords();
161 std::vector<uint32_t>::const_iterator it = vDataWords.begin();
162 std::vector<uint32_t>::const_iterator end = vDataWords.end();
163 for (; it != end; ++it) {
164 theROD->push_back(*it);
165 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setw(8) << (*it));
166 }
167
168 // Now fill full event
169 ATH_MSG_DEBUG("Now filling the event with the L1Topo fragment");
170 fea.fill(re, msg());
171
172 return StatusCode::SUCCESS;
173}
174
175StatusCode L1TopoByteStreamTool::convert(const EventContext& ctx,
176 const std::string& sgKey,
177 L1TopoRDOCollection* result) const {
178 //
179 // Get the ROB fragment:
180 //
182 m_robDataProvider->getROBData(ctx, m_sourceIDs, robFrags);
183
184 if (robFrags.size() == 0) {
185 ATH_MSG_WARNING("No ROB fragments found");
186 return StatusCode::SUCCESS;
187 }
188
189 for (auto it : robFrags) {
190 L1TopoRDO* rdo = nullptr;
191 StatusCode sc = convert(ROBData(it).getROBFragment(), rdo);
192 if (sc.isFailure()) {
193 ATH_MSG_ERROR(" Failed to create Objects: " << sgKey);
194 delete rdo;//memory was allocated by convert
195 return sc;
196 } else {
197 result->push_back(rdo); // append a copy of the pointer to the
198 // collection, i.e. takes ownership of the new
199 // L1TopoRDO.
200 }
201 }
202 return StatusCode::SUCCESS;
203}
204
209// change to VROBFRAG and use IROBDataProviderSvc::VROBFRAG::const_iterator to
210// loop over them
211StatusCode L1TopoByteStreamTool::convert(const ROBF* rob, L1TopoRDO*& result) const {
212 ATH_MSG_DEBUG("executing convert() from ROBFragment to RDO");
213
214 uint32_t rodId = rob->rob_source_id();
215
216 ATH_MSG_DEBUG("expected ROD sub-detector ID: " << MSG::hex << m_sourceIDs
217 << " ID found: " << MSG::hex
218 << rodId << MSG::dec);
219
220 bool idMatch = false;
221 for (auto id : m_sourceIDs) {
222 if (rodId == id) {
223 idMatch = true;
224 }
225 }
226 if (idMatch) {
227 // Need to check S-link trailer for errors - this would be propagated to
228 // status word, see below.
229 // First use ROB & ROD error check methods
230 bool error_rob(false);
231 bool error_rod(false);
232 try {
233 if (rob->check_rob()) {
234 ATH_MSG_VERBOSE("ROB fragment checked ok");
235 }
236 } catch (std::exception const& ex) {
237 ATH_MSG_WARNING("ROB fragment not valid: " << ex.what());
238 error_rob = true;
239 }
240 try {
241 if (rob->check_rod()) {
242 ATH_MSG_VERBOSE("ROD fragment checked ok");
243 }
244 } catch (std::exception const& ex) {
245 ATH_MSG_WARNING("ROD fragment not valid: " << ex.what());
246 error_rod = true;
247 }
248
249 // Print some header info
251 MSG::hex << " \n"
252 << " rod_version 0x" << rob->rod_version() << " \n"
253 << " rod_run_no 0x" << MSG::dec
254 << rob->rod_run_no() << " \n"
255 << " rod_lvl1_id 0x" << MSG::hex
256 << rob->rod_lvl1_id() << " \n"
257 << " rod_bc_id 0x" << rob->rod_bc_id() << " \n"
258 << " rod_lvl1_trigger_type 0x" << rob->rod_lvl1_trigger_type()
259 << " \n"
260 << " nchildren 0x" << rob->nchildren() << " \n"
261 << MSG::dec);
262
263 // print and check status words
264 OFFLINE_FRAGMENTS_NAMESPACE::PointerType it_status = rob->rod_status();
265 const uint32_t nstatus = rob->rod_nstatus();
266 ATH_MSG_VERBOSE("Number of status words: " << nstatus);
267 std::vector<uint32_t> vStatusWords;
268 vStatusWords.reserve(nstatus);
269 ATH_MSG_VERBOSE("Dumping ROD status words:");
270 for (uint32_t i = 0; i < nstatus; ++i, ++it_status) {
271 vStatusWords.push_back(static_cast<uint32_t>(*it_status));
272 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8)
273 << *it_status << MSG::dec);
274 }
275 // for definition of first status word see:
276 // - bits 00-15: https://edms.cern.ch/document/445840/5.0a section 5.8
277 // - bits 16-31: bits 16-31:
278 // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/ROBINFragmentErrors
279 // Can do something more specific eventually.
280 bool error_status(false);
281 if (vStatusWords.size() == 0) {
282 ATH_MSG_WARNING("ROD has no status word");
283 }
284 if (vStatusWords.size() > 0 && vStatusWords.at(0) != 0) {
285 ATH_MSG_WARNING("Non-zero first status word, payload may not be valid");
286 error_status = true;
287 }
288
289 // print and interpret data words and save them for RDO
290 OFFLINE_FRAGMENTS_NAMESPACE::PointerType it_data = rob->rod_data();
291 const uint32_t ndata = rob->rod_ndata();
292 ATH_MSG_VERBOSE("Number of data words: " << ndata);
293
294 ATH_MSG_VERBOSE("Dumping L1Topo data words:");
295 std::vector<uint32_t> vDataWords;
296 vDataWords.reserve(ndata);
297 for (uint32_t i = 0; i < ndata; ++i, ++it_data) {
298 vDataWords.push_back(static_cast<uint32_t>(*it_data));
299 ATH_MSG_VERBOSE(" 0x" << MSG::hex << std::setfill('0') << std::setw(8)
300 << *it_data << MSG::dec);
301 }
302
303 // create L1Topo RDO
304 result = new L1TopoRDO();
305 result->setDataWords(std::move(vDataWords));
306 result->setStatusWords(std::move(vStatusWords));
307 if (error_status) {
308 result->setError(L1Topo::Error::SLINK_STATUS_ERROR);
309 }
310 if (error_rob) {
311 result->setError(L1Topo::Error::ROB_ERROR);
312 }
313 if (error_rod) {
314 result->setError(L1Topo::Error::ROD_ERROR);
315 }
316 result->setSourceID(rodId);
317
318 return StatusCode::SUCCESS;
319 }
320
321 ATH_MSG_ERROR("Wrong ROD ID found in the L1Topo ROB fragment!");
322 return StatusCode::FAILURE;
323}
const boost::regex re(r_e)
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
static const InterfaceID IID_IL1TopoByteStreamTool("L1TopoByteStreamTool", 1, 0)
Unique interface ID of the tool that identifies it to the framweork.
static Double_t sc
Defines the ROB data entity. The ROB data is an abstract entity that is used to decouple the raw even...
ROBData_T< OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment, OFFLINE_FRAGMENTS_NAMESPACE::PointerType > ROBData
Definition ROBData.h:225
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::FullEventFragment RawEventWrite
data type for writing raw event
Definition RawEvent.h:39
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
MsgStream & msg() const
Template class for assembling a full atlas raw event from subfragments.
void setRodMinorVersion(uint16_t m)
change the ROD minor version
void fill(RawEventWrite *re, MsgStream &log)
Fill the FullEventFragment with all the ROD data stored in this.
void setDetEvtType(uint32_t m)
change Detector Event Type
std::vector< uint32_t > RODDATA
ROD data as a vector of unsigned int.
RODDATA * getRodData(uint32_t id)
get a block of ROD data
std::vector< const ROBF * > VROBFRAG
static const InterfaceID & interfaceID()
AlgTool InterfaceID.
ServiceHandle< IROBDataProviderSvc > m_robDataProvider
Service for reading bytestream.
virtual StatusCode initialize()
Function to initialise the tool.
OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment ROBF
L1TopoByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
virtual StatusCode finalize()
Function to finalise the tool.
std::vector< uint32_t > m_sourceIDs
Source IDs of L1Topo RODs.
const std::vector< uint32_t > & sourceIDs()
return list of L1Topo ROD source IDs to use, defaults to DAQ ROD IDs
L1TopoSrcIdMap * m_srcIdMap
Object to generate and convert between the various IDs of the L1Topo fragment.
StatusCode convert(const EventContext &ctx, const std::string &sgKey, L1TopoRDOCollection *result) const
Convert ROBFragment to L1TopoRDO.
virtual ~L1TopoByteStreamTool()
Default destructor.
Container of L1TopoRDOs (standard Athena boilerplate).
The class that represents the raw data received from an L1Topo board.
Definition L1TopoRDO.h:29
This class provides conversion between Lower level Source ID to higher level source ID for L1Topo Byt...
Represents the L1Topo module ID, with decoder and encoder.
Definition ModuleID.h:28
uint16_t id() const
access method
Definition ModuleID.cxx:41
@ SLINK_STATUS_ERROR
Definition Error.h:16
const DataType * PointerType
Definition RawEvent.h:25