CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AMC13Spec.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <map>
3 
7 
9 
10 #define EDM_ML_DEBUG 1
11 
12 namespace amc13 {
13  Header::Header(unsigned int namc, unsigned int orbit)
14  {
15  data_ =
16  (static_cast<uint64_t>(namc & nAMC_mask) << nAMC_shift) |
17  (static_cast<uint64_t>(orbit & OrN_mask) << OrN_shift) |
18  (static_cast<uint64_t>(fov & uFOV_mask) << uFOV_shift);
19  }
20 
21  bool
22  Header::check() const
23  {
24  return (getNumberOfAMCs() <= max_amc) && (getFormatVersion() == fov);
25  }
26 
27  Trailer::Trailer(unsigned int blk, unsigned int lv1, unsigned int bx)
28  {
29  data_ =
30  (static_cast<uint64_t>(blk & BlkNo_mask) << BlkNo_shift) |
31  (static_cast<uint64_t>(lv1 & LV1_mask) << LV1_shift) |
32  (static_cast<uint64_t>(bx & BX_mask) << BX_shift);
33  }
34 
35  bool
36  Trailer::check(unsigned int crc, unsigned int block, unsigned int lv1_id, unsigned int bx) const
37  {
38  if ((crc != 0 && crc != getCRC()) || block != getBlock() || (lv1_id & LV1_mask) != getLV1ID() || (bx & BX_mask) != getBX()) {
39  edm::LogWarning("L1T")
40  << "Found AMC13 trailer with:"
41  << "\n\tBX " << getBX() << ", LV1 ID " << getLV1ID() << ", block # " << getBlock()
42  << ", CRC " << std::hex << std::setw(8) << std::setfill('0') << getCRC() << std::dec
43  << "\nBut expected:"
44  << "\n\tBX " << (bx & BX_mask) << ", LV1 ID " << (lv1_id & LV1_mask) << ", block # " << block
45  << ", CRC " << std::hex << std::setw(8) << std::setfill('0') << crc;
46  return false;
47  }
48  return true;
49  }
50 
51  void
53  {
54  std::string dstring(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(end) + 4);
55  auto crc = cms::CRC32Calculator(dstring).checksum();
56 
57  *end = ((*end) & ~(uint64_t(CRC_mask) << CRC_shift)) | (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift);
58  }
59 
60  void
61  Packet::add(unsigned int amc_no, unsigned int board, unsigned int lv1id, unsigned int orbit, unsigned int bx, const std::vector<uint64_t>& load)
62  {
63  edm::LogInfo("AMC") << "Adding board " << board << " with payload size " << load.size()
64  << " as payload #" << amc_no;
65  // Start by indexing with 1
66  payload_.push_back(amc::Packet(amc_no, board, lv1id, orbit, bx, load));
67  }
68 
69  bool
70  Packet::parse(const uint64_t *start, const uint64_t *data, unsigned int size, unsigned int lv1, unsigned int bx, bool legacy_mc)
71  {
72  // Need at least a header and trailer
73  // TODO check if this can be removed
74  if (size < 2) {
75  edm::LogError("AMC") << "AMC13 packet size too small";
76  return false;
77  }
78 
79  std::map<int, int> amc_index;
80 
81  header_ = Header(data++);
82 
83  if (!header_.check()) {
84  edm::LogError("AMC")
85  << "Invalid header for AMC13 packet: "
86  << "format version " << header_.getFormatVersion()
87  << ", " << header_.getNumberOfAMCs()
88  << " AMC packets";
89  return false;
90  }
91 
92  if (size < 2 + header_.getNumberOfAMCs())
93  return false;
94 
95  // Initial filling of AMC payloads. First, get the headers. The
96  // first payload follows afterwards.
97  for (unsigned int i = 0; i < header_.getNumberOfAMCs(); ++i) {
98  payload_.push_back(amc::Packet(data++));
99  amc_index[payload_.back().blockHeader().getAMCNumber()] = i;
100  }
101 
102  unsigned int tot_size = 0; // total payload size
103  unsigned int tot_nblocks = 0; // total blocks of payload
104  unsigned int maxblocks = 0; // counting the # of amc13 header/trailers (1 ea per block)
105 
106  bool check_crc = false;
107  for (const auto& amc: payload_) {
108  tot_size += amc.blockHeader().getSize();
109  tot_nblocks += amc.blockHeader().getBlocks();
110  maxblocks = std::max(maxblocks, amc.blockHeader().getBlocks());
111 
112  if (amc.blockHeader().validCRC())
113  check_crc = true;
114  }
115 
116  unsigned int words = tot_size + // payload size
117  tot_nblocks + // AMC headers
118  2 * maxblocks; // AMC13 headers
119 
120  if (size < words) {
121  edm::LogError("L1T")
122  << "Encountered AMC 13 packet with "
123  << size << " words, "
124  << "but expected "
125  << words << " words: "
126  << tot_size << " payload words, "
127  << tot_nblocks << " AMC header words, and 2 AMC 13 header words.";
128  return false;
129  }
130 
131  // Read in the first AMC block and append the payload to the
132  // corresponding AMC packet.
133  for (auto& amc: payload_) {
134  amc.addPayload(data, amc.blockHeader().getBlockSize());
135  data += amc.blockHeader().getBlockSize();
136  }
137 
138  Trailer t(data++);
139 
140  int crc = 0;
141  if (check_crc) {
142  std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
143  crc = cms::CRC32Calculator(check).checksum();
144 
145  LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
146  }
147 
148  t.check(crc, 0, lv1, bx);
149 
150  // Read in remaining AMC blocks
151  for (unsigned int b = 1; b < maxblocks; ++b) {
152  Header block_h(data++);
153  std::vector<amc::BlockHeader> headers;
154 
155  for (unsigned int i = 0; i < block_h.getNumberOfAMCs(); ++i)
156  headers.push_back(amc::BlockHeader(data++));
157 
158  check_crc = false;
159  for (const auto& amc: headers) {
160  payload_[amc_index[amc.getAMCNumber()]].addPayload(data, amc.getBlockSize());
161  data += amc.getBlockSize();
162 
163  if (amc.validCRC())
164  check_crc = true;
165  }
166 
167  t = Trailer(data++);
168 
169  if (check_crc) {
170  std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
171  crc = cms::CRC32Calculator(check).checksum();
172 
173  LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
174  } else {
175  crc = 0;
176  }
177 
178  t.check(crc, b, lv1, bx);
179  }
180 
181  for (auto& amc: payload_) {
182  amc.finalize(lv1, bx, legacy_mc);
183  }
184 
185  return true;
186  }
187 
188  unsigned int
190  {
191  unsigned int maxblocks = 0;
192 
193  for (const auto& amc: payload_)
194  maxblocks = std::max(maxblocks, amc.blocks());
195 
196  return maxblocks;
197  }
198 
199  unsigned int
200  Packet::size() const
201  {
202  unsigned int words = 0;
203  unsigned int blocks = 0;
204  unsigned int maxblocks = 0;
205 
206  for (const auto& amc: payload_) {
207  words += amc.header().getSize();
208  blocks += amc.blocks();
209  maxblocks = std::max(maxblocks, amc.blocks());
210  }
211 
212  // Size is total amount of words + # of blocks for AMC headers + # of
213  // maxblocks for AMC13 block header, trailer
214  return words + blocks + maxblocks * 2;
215  }
216 
217  bool
218  Packet::write(const edm::Event& ev, unsigned char * ptr, unsigned int skip, unsigned int size) const
219  {
220  if (size < this->size() * 8)
221  return false;
222 
223  if (size % 8 != 0)
224  return false;
225 
226  uint64_t * data = reinterpret_cast<uint64_t*>(ptr + skip);
227 
228  for (unsigned int b = 0; b < blocks(); ++b) {
229  // uint64_t * block_start = data;
230 
231  std::vector<uint64_t> block_headers;
232  std::vector<uint64_t> block_load;
233  for (const auto& amc: payload_) {
234  edm::LogInfo("AMC")
235  << "Considering block " << b
236  << " for payload " << amc.blockHeader().getBoardID()
237  << " with size " << amc.size()
238  << " and " << amc.blocks() << " blocks";
239  if (amc.blocks() < b + 1)
240  continue;
241 
242  block_headers.push_back(amc.blockHeader(b));
243  auto words = amc.block(b);
244  block_load.insert(block_load.end(), words.begin(), words.end());
245  }
246 
247  if (b == 0) {
248  amc13::Header h(block_headers.size(), ev.orbitNumber());
249  edm::LogInfo("AMC")
250  << "Writing header for AMC13 packet: "
251  << "format version " << h.getFormatVersion()
252  << ", " << h.getNumberOfAMCs()
253  << " AMC packets, orbit " << h.getOrbitNumber();
254  }
255 
256  *(data++) = amc13::Header(block_headers.size(), ev.orbitNumber()).raw();
257 
258  block_headers.insert(block_headers.end(), block_load.begin(), block_load.end());
259  for (const auto& word: block_headers)
260  *(data++) = word;
261 
262  *data = Trailer(b, ev.id().event(), ev.bunchCrossing()).raw();
263  Trailer::writeCRC(reinterpret_cast<uint64_t*>(ptr), data);
264  }
265 
266  return true;
267  }
268 }
#define LogDebug(id)
EventNumber_t event() const
Definition: EventID.h:41
tuple t
Definition: tree.py:139
int i
Definition: DBlmapReader.cc:9
Header header_
Definition: AMC13Spec.h:80
static const unsigned int OrN_shift
Definition: AMC13Spec.h:33
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
static const unsigned int LV1_mask
Definition: AMC13Spec.h:62
static void writeCRC(const uint64_t *start, uint64_t *end)
Definition: AMC13Spec.cc:52
static const unsigned int fov
Definition: AMC13Spec.h:36
unsigned int size() const
Definition: AMC13Spec.cc:200
unsigned int getCRC() const
Definition: AMC13Spec.h:47
unsigned int blocks() const
Definition: AMC13Spec.cc:189
static const unsigned int nAMC_mask
Definition: AMC13Spec.h:32
bool check(unsigned int crc, unsigned int block, unsigned int lv1_id, unsigned int bx) const
Definition: AMC13Spec.cc:36
static const unsigned int CRC_mask
Definition: AMC13Spec.h:58
static const unsigned int BlkNo_mask
Definition: AMC13Spec.h:60
int bunchCrossing() const
Definition: EventBase.h:66
static const unsigned int BX_mask
Definition: AMC13Spec.h:64
bool ev
bool write(const edm::Event &ev, unsigned char *ptr, unsigned int skip, unsigned int size) const
Definition: AMC13Spec.cc:218
uint64_t data_
Definition: AMC13Spec.h:39
Trailer(const uint64_t *data)
Definition: AMC13Spec.h:44
std::vector< amc::Packet > payload_
Definition: AMC13Spec.h:84
unsigned int getBX() const
Definition: AMC13Spec.h:50
unsigned int getBlock() const
Definition: AMC13Spec.h:48
uint64_t data_
Definition: AMC13Spec.h:66
bool check(const std::string &)
static const unsigned int uFOV_shift
Definition: AMC13Spec.h:29
double amc
Definition: hdecay.h:20
static const unsigned int BX_shift
Definition: AMC13Spec.h:63
def load
Definition: svgfig.py:546
static const unsigned int uFOV_mask
Definition: AMC13Spec.h:30
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define end
Definition: vmac.h:37
int orbitNumber() const
Definition: EventBase.h:67
unsigned int getLV1ID() const
Definition: AMC13Spec.h:49
static const unsigned int max_amc
Definition: AMC13Spec.h:37
unsigned long long uint64_t
Definition: Time.h:15
void add(unsigned int amc_no, unsigned int board, unsigned int lv1id, unsigned int orbit, unsigned int bx, const std::vector< uint64_t > &load)
Definition: AMC13Spec.cc:61
double b
Definition: hdecay.h:120
static const unsigned int nAMC_shift
Definition: AMC13Spec.h:31
static const unsigned int LV1_shift
Definition: AMC13Spec.h:61
static const unsigned int BlkNo_shift
Definition: AMC13Spec.h:59
unsigned int getNumberOfAMCs() const
Definition: AMC13Spec.h:25
unsigned int getFormatVersion() const
Definition: AMC13Spec.h:24
edm::EventID id() const
Definition: EventBase.h:60
bool parse(const uint64_t *start, const uint64_t *data, unsigned int size, unsigned int lv1, unsigned int bx, bool legacy_mc=false)
Definition: AMC13Spec.cc:70
static const unsigned int CRC_shift
Definition: AMC13Spec.h:57
std::uint32_t checksum()
bool check() const
Definition: AMC13Spec.cc:22
tuple size
Write out results.
static const unsigned int OrN_mask
Definition: AMC13Spec.h:34