ATLAS Offline Software
Loading...
Searching...
No Matches
NSWElink.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4#include <vector>
5#include <exception>
6#include <sstream>
7
8#include "ers/ers.h"
9
12
16
18
19Muon::nsw::NSWElink::NSWElink (const uint32_t *bs, const uint32_t remaining)
20 : m_wordCount (0)
21{
22 m_rocId = 0; // Fix coverity warning
23
24 // Felix header (2 words)
25 // Packet length includes Felix header
26
27 uint32_t word = bs[m_wordCount++];
30
31 if (m_packet_status != 0)
32 {
33 std::ostringstream s;
34 s << "Packet status in FELIX header 0x" << std::hex << m_packet_status << std::dec;
35 Muon::nsw::MuonNSWCommonDecoder::NSWElinkFelixHeaderException e (ERS_HERE, s.str ());
36 throw e;
37 }
38
39 if (remaining * sizeof (uint32_t) < packet_nbytes)
40 {
41 std::ostringstream s;
42 s << "Packet length in FELIX header " << packet_nbytes << " is larger than available data";
43 Muon::nsw::MuonNSWCommonDecoder::NSWElinkFelixHeaderException e (ERS_HERE, s.str ());
44 throw e;
45 }
46
49
50 // Decode sROC header
51
52 word = bs[m_wordCount++];
53
54 ERS_DEBUG (2, "==============================================================");
55 ERS_DEBUG (2, "FELIX HEADER: LENGTH (BYTES) = " << packet_nbytes <<
56 " | STATUS = " << m_packet_status << " | RESOURCE ID = 0x" << std::hex << m_elinkWord << std::dec);
57
59 {
62
63 ERS_DEBUG (2, "ROC HEADER: | NULL = " << m_isNull <<
64 " | ROCID = " << m_rocId << " | L1ID = " << m_l1Id);
65
66 // It may happen that the packet is flagged as a null packet but there are additional bytes
67
68 if (packet_nbytes != s_null_packet_length)
69 {
70 std::ostringstream s;
71 s << "Additional data detected in packet flagged as null " << packet_nbytes;
72 Muon::nsw::MuonNSWCommonDecoder::NSWElinkROCHeaderException e (ERS_HERE, s.str ());
73
74 // Additional words are ignored
75
76 m_wordCount = packet_nbytes / sizeof (uint32_t);
77 }
78 }
79 else
80 {
81 // It may happen that the null packet flag is wrong (or the size is wrong)
82 // In that case, throw an exception
83
84 if (packet_nbytes == s_null_packet_length)
85 {
86 std::ostringstream s;
87 s << "Packet length in FELIX header " << packet_nbytes << " and null event flag in packet are inconsistent";
88 Muon::nsw::MuonNSWCommonDecoder::NSWElinkROCHeaderException e (ERS_HERE, s.str ());
89 throw e;
90 }
91
92 // Calculate packet checksum
93
94 const uint8_t *p = reinterpret_cast <const uint8_t *> (bs + 2);
95 m_running_checksum = this->test_checksum (p, (packet_nbytes - 2 * sizeof (uint32_t)));
96
97 // m_noTDC will only affect data size, hit words should be re-aligned to uint32_t
98
103
104 // Set hit bytes to correspond to the length in Flx header
105 // Everything should be re-aligned in the swROD, though
106
107 // const unsigned int hit_size = m_noTdc ? 3 : 4; // set hit bytes to correspond to the length in Flx header
108
109 // Hit size should always be 4, since (at least for run 3) the detector is always configured to get the TDC info
110 // Please keep the previous commented out line. Having noTdc = true is a legal condition, in principle,
111 // but given the actual configuration of the detector, that should never happen and a crash is provoked when it does if
112 // it is taken into account. I (EP) added a warning exception to report that condition.
113
114 static const unsigned int hit_size = 4;
115
116 if (m_noTdc)
117 {
118 std::ostringstream s;
119 s << "Hit size is not compatible with flags in ROC header, elink ID = " << m_elinkWord << " L1 ID = " << m_l1Id;
120 Muon::nsw::MuonNSWCommonDecoder::NSWElinkROCHeaderException e (ERS_HERE, s.str ());
121 ers::warning (e);
122 }
123
124 // Two 32-bits words for Felix header, 1 word for ROC header, 1 word for the ROC trailer
125
126 m_nhits = (packet_nbytes - 4 * sizeof (uint32_t)) / hit_size;
127 if (packet_nbytes % 4) ++m_nhits;
128
129 ERS_DEBUG (2, "ROC HEADER: T = " << m_noTdc << " | NULL = " << m_isNull <<
130 " | ORBIT = " << m_orbit << " | BCID = " << m_bcId << " | L1ID = " << m_l1Id);
131
132 // Hit Data
133
134 for (unsigned int i=0; i < m_nhits; ++i)
135 {
137 m_channels.push_back(c);
138 }
139
140 // ROC Trailer (1 word)
141
142 word = bs[m_wordCount++];
143
150
151 ERS_DEBUG (2, "ROC TRAILER: EXTENDED = " << m_extended << " | TIMEOUT = " << m_tout << std::hex <<
152 " | FLAGMISS = 0x" << m_flagMiss << std::dec << " | L0ID = " << m_l0Id << " | NHITS = " << m_nhits <<
153 " | CHECKSUM = 0x" << std::hex << static_cast <unsigned int> (m_checksum) << std::dec);
154 ERS_DEBUG (2, "PACKET CHECKSUM = " << m_running_checksum);
155 }
156}
157
159{
160 for (auto i = m_channels.begin (); i != m_channels.end (); ++i)
161 delete *i;
162
163 delete m_elinkId;
164}
165
uint32_t get_bits(uint32_t word, uint32_t mask, uint8_t position)