CMS 3D CMS Logo

HGCalRawDataPackingTools.cc
Go to the documentation of this file.
5 
6 std::vector<uint32_t> hgcal::econd::produceERxData(const ERxChannelEnable& channel_enable,
7  const ERxData& erx,
8  bool passZS,
9  bool passZSm1,
10  bool hasToA,
11  bool char_mode) {
12  auto format_word = [&erx, &passZS, &passZSm1, &hasToA, &char_mode](size_t i) -> std::pair<uint32_t, uint8_t> {
13  if (i >= erx.tctp.size())
14  throw cms::Exception("HGCalEmulator")
15  << "Not enough channels in eRx data payload: " << i << " >= " << erx.tctp.size() << ".";
16  if (char_mode) // characterisation mode is easy
17  return std::make_pair(((uint8_t)erx.tctp.at(i) & 0x3) << 30 | (erx.adc.at(i) & 0x3ff) << 20 |
18  (erx.tot.at(i) & 0x3ff) << 10 | (erx.toa.at(i) & 0x3ff),
19  32);
20  switch (erx.tctp.at(i)) {
22  if (!passZS)
23  throw cms::Exception("HGCalEmulator") << "ToT status is ZeroSuppressed, but event frame does not pass ZS.";
24  if (passZSm1) {
25  if (hasToA)
26  return std::make_pair((0x1 << 30) | ((erx.adcm.at(i) & 0x3ff) << 20) | ((erx.adc.at(i) & 0x3ff) << 10) |
27  (erx.toa.at(i) & 0x3ff),
28  32);
29  else
30  return std::make_pair(((erx.adcm.at(i) & 0x3ff) << 10) | (erx.adc.at(i) & 0x3ff), 24);
31  }
32  // at this point, does not have any BX-1 ZS info
33  if (hasToA)
34  return std::make_pair((0x3 << 20) | ((erx.adc.at(i) & 0x3ff) << 10) | (erx.toa.at(i) & 0x3ff), 24);
35  return std::make_pair((0x1 << 10) | (erx.adc.at(i) & 0x3ff), 16);
36  }
38  return std::make_pair((0x2 << 20) | ((erx.adcm.at(i) & 0x3ff) << 10) | (erx.adc.at(i) & 0x3ff), 24);
39  case ToTStatus::invalid:
40  return std::make_pair(
41  (0x2 << 30) | ((erx.adcm.at(i) & 0x3ff) << 20) | ((erx.adc.at(i) & 0x3ff) << 10) | (erx.toa.at(i) & 0x3ff),
42  32);
44  return std::make_pair(
45  (0x3 << 30) | ((erx.adcm.at(i) & 0x3ff) << 20) | ((erx.tot.at(i) & 0x3ff) << 10) | (erx.toa.at(i) & 0x3ff),
46  32);
47  default:
48  throw cms::Exception("HGCalEmulator")
49  << "Invalid ToT status retrieved for channel " << i << ": " << (int)erx.tctp.at(i) << ".";
50  }
51  };
52 
53  std::vector<uint32_t> data{0};
54  std::vector<uint32_t>::iterator it_data = data.begin();
55 
56  uint8_t msb = 0;
57  for (size_t i = 0; i < channel_enable.size(); ++i) {
58  if (!channel_enable.at(i))
59  continue;
60  const auto [word, nbits] = format_word(i); // retrieve the channel word in its proper formatting
61 
62  if (msb >= 32) // if we are already at the next word
63  it_data = data.insert(data.end(), 0);
64  msb %= 32; // 0 <= msb < 32
65 
66  if (msb > 0) // do we have some room for additional information?
67  *it_data &= ((1 << msb) - 1);
68  if (msb + nbits > 32) { // spilling onto the next word
69  uint8_t nbits_word1 = 32 - msb - nbits;
70  *it_data |= (word & ((1 << nbits_word1) - 1)) << msb;
71  it_data = data.insert(data.end(), word >> nbits_word1);
72  } else // everything fits into one word
73  *it_data |= word << msb;
74  msb += nbits;
75  }
76  return data;
77 }
78 
79 //
80 std::vector<uint32_t> hgcal::econd::eRxSubPacketHeader(uint8_t stat,
81  uint8_t hamming,
82  bool bitE,
83  uint16_t common_mode0,
84  uint16_t common_mode1,
85  const ERxChannelEnable& channel_enable) {
86  uint64_t channels_map64b(0);
87  size_t i = 0;
88  for (const auto& ch : channel_enable)
89  channels_map64b |= (ch << i++);
90  return hgcal::econd::eRxSubPacketHeader(stat, hamming, bitE, common_mode0, common_mode1, channels_map64b);
91 }
92 
93 //
94 std::vector<uint32_t> hgcal::econd::eRxSubPacketHeader(
95  uint8_t stat, uint8_t hamming, bool bitE, uint16_t common_mode0, uint16_t common_mode1, uint64_t channels_map) {
96  std::vector<uint32_t> header = {
101 
102  //summarize the channel status map
103  const uint32_t chmapw0(channels_map & hgcal::ECOND_FRAME::CHMAP0_MASK),
104  chmapw1((channels_map >> 32) & hgcal::ECOND_FRAME::CHMAP32_MASK);
105 
106  //add the channel map
107  if (chmapw0 == 0 && chmapw1 == 0) { // empty channels map (empty eRx)
108  header[0] |= (bitE << hgcal::ECOND_FRAME::ERX_E_POS);
109  header[0] |= (1 << hgcal::ECOND_FRAME::ERXFORMAT_POS); //raise the F bit (empty eRX)
110  } else {
113  }
114 
115  return header;
116 }
117 
118 static uint8_t computeCRC8bit(const std::vector<uint32_t>& event_header) {
119  uint8_t crc = 0x42; //TODO: implement 8-bit Bluetooth CRC
120  return crc;
121 }
122 
123 //
124 std::vector<uint32_t> hgcal::econd::eventPacketHeader(uint16_t header,
125  uint16_t payload,
126  bool bitP,
127  bool bitE,
128  uint8_t ht,
129  uint8_t ebo,
130  bool bitM,
131  bool bitT,
132  uint8_t ehHam,
133  uint16_t bx,
134  uint16_t l1a,
135  uint8_t orb,
136  bool bitS,
137  uint8_t rr) {
138  std::vector<uint32_t> words(2, 0);
139 
147 
152 
153  const auto crc = computeCRC8bit(words);
155 
156  return words;
157 }
158 
159 uint32_t hgcal::econd::buildIdleWord(uint8_t bufStat, uint8_t err, uint8_t rr, uint32_t progPattern) {
160  return (progPattern & 0xffffff) << 8 | (rr & 0x3) << 6 | (err & 0x7) << 3 | (bufStat & 0x7) << 0;
161 }
162 
163 //
165  uint32_t bunch_crossing,
166  uint32_t event_counter,
167  uint32_t orbit_counter,
168  const std::vector<hgcal::backend::ECONDPacketStatus>& econd_statuses) {
169  if (econd_statuses.size() > 12)
170  throw cms::Exception("HGCalEmulator") << "Invalid size for ECON-D statuses: " << econd_statuses.size() << ".";
171  std::vector<uint32_t> header(2, 0);
172  header[0] =
176  (econd_statuses[11] & 0x7) << 1 | ((econd_statuses[10] >> 2) & 0x1);
177  for (size_t i = 0; i < 11; i++)
178  header[1] |= (econd_statuses[i] & 0x7) << i * 3;
179  return header;
180 }
181 
182 //
183 std::vector<uint32_t> hgcal::backend::buildSlinkHeader(
184  uint8_t boe, uint8_t v, uint64_t global_event_id, uint32_t content_id, uint32_t fed_id) {
185  std::vector<uint32_t> header(4, 0);
188  ((global_event_id >> 41) & SLINK_GLOBAL_EVENTID_MSB_MASK)
190  header[1] = (global_event_id & SLINK_GLOBAL_EVENTID_LSB_MASK);
193 
194  return header;
195 }
196 
197 //
198 std::vector<uint32_t> hgcal::backend::buildSlinkTrailer(uint8_t eoe,
199  uint16_t daqcrc,
200  uint32_t event_length,
201  uint16_t bxid,
202  uint32_t orbit_id,
203  uint16_t crc,
204  uint16_t status) {
205  std::vector<uint32_t> trailer(4, 0);
206 
214 
215  return trailer;
216 }
217 
218 //
219 uint32_t hgcal::backend::buildSlinkContentId(SlinkEmulationFlag e, uint8_t l1a_subtype, uint16_t l1a_fragment_cnt) {
220  return 0x0 | (l1a_fragment_cnt & 0xffff) | (l1a_subtype & 0xff) << 16 | (e & 0x3) << 24;
221 }
222 
224  bool fed_crc_err, bool slinkrocket_crc_err, bool source_id_err, bool sync_lost, bool fragment_trunc) {
225  return 0x0 | (fed_crc_err & 0x1) << 0 | (slinkrocket_crc_err & 0x1) << 1 | (source_id_err & 0x1) << 2 |
226  (sync_lost & 0x1) << 3 | (fragment_trunc & 0x1) << 4;
227 }
std::vector< ToTStatus > tctp
Definition: SlinkTypes.h:22
std::vector< uint32_t > produceERxData(const ERxChannelEnable &, const ERxData &, bool passZS, bool passZSm1, bool hasToA, bool char_mode)
std::vector< uint32_t > buildCaptureBlockHeader(uint32_t bunch_crossing, uint32_t event_counter, uint32_t orbit_counter, const std::vector< ECONDPacketStatus > &econd_statuses)
std::vector< uint32_t > eRxSubPacketHeader(uint8_t stat, uint8_t ham, bool bitE, uint16_t common_mode0, uint16_t common_mode1, const ERxChannelEnable &channel_enable)
parsed e-rx data
Definition: SlinkTypes.h:20
uint32_t buildSlinkContentId(SlinkEmulationFlag, uint8_t l1a_subtype, uint16_t l1a_fragment_cnt)
std::vector< bool > ERxChannelEnable
list of channels enabled in eRx
Definition: SlinkTypes.h:38
std::vector< uint16_t > tot
Definition: SlinkTypes.h:23
std::vector< uint16_t > toa
Definition: SlinkTypes.h:23
uint64_t word
std::vector< uint32_t > buildSlinkHeader(uint8_t boe, uint8_t v, uint64_t global_event_id, uint32_t content_id, uint32_t fed_id)
uint32_t buildIdleWord(uint8_t bufStat, uint8_t err, uint8_t rr, uint32_t progPattern)
uint16_t buildSlinkRocketStatus(bool fed_crc_err, bool slinkrocket_crc_err, bool source_id_err, bool sync_lost, bool fragment_trunc)
unsigned long long uint64_t
Definition: Time.h:13
std::vector< uint16_t > adc
Definition: SlinkTypes.h:23
std::vector< uint32_t > buildSlinkTrailer(uint8_t eoe, uint16_t daqcrc, uint32_t event_length, uint16_t bxid, uint32_t orbit_id, uint16_t crc, uint16_t status)
static uint8_t computeCRC8bit(const std::vector< uint32_t > &event_header)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
std::vector< uint32_t > eventPacketHeader(uint16_t header, uint16_t payload, bool bitP, bool bitE, uint8_t ht, uint8_t ebo, bool bitM, bool bitT, uint8_t hamming, uint16_t bx, uint16_t l1a, uint8_t orb, bool bitS, uint8_t RR)
std::vector< uint16_t > adcm
Definition: SlinkTypes.h:23