CMS 3D CMS Logo

Block.cc
Go to the documentation of this file.
1 #include <iomanip>
2 
4 
6 
7 #define EDM_ML_DEBUG 1
8 
9 namespace l1t {
10 
11  const std::vector<unsigned int>
13  {
14  // The "0b" prefix indicates binary; the block header id is stored in decimal.
15  // Bits are the left-most bit (D15) of every 16-bit word in the format document.
16  // Bottom-to-top in the document maps to left-to-right in each of the block_patterns_
17  0b000111111111, // Event Record Header : block->header().getID() = 511
18  // Left-most bits of 0xA and 0x9 are both 1 in binary
19  0b0010, // Block of Counters : block->header().getID() = 2
20  0b0011, // ME Data Record : block->header().getID() = 3
21  0b0100, // RPC Data Record : block->header().getID() = 4
22  0b01100101, // SP Output Data Record : block->header().getID() = 101
23  0b11111111 // Event Record Trailer : block->header().getID() = 255
24  // Left-most bits of 0xF and 0xE are both 1 in binary
25  };
26 
27  uint32_t
29  {
30  if (type_ == MP7) {
31  LogTrace("L1T") << "Writing MP7 link header";
32  return ((id_ & ID_mask) << ID_shift) | ((size_ & size_mask) << size_shift) | ((capID_ & capID_mask) << capID_shift) | ((flags_ & flags_mask) << flags_shift);
33  }
34  else if (type_ == CTP7) {
35  LogTrace("L1T") << "Writing CTP7 link header";
36  return flags_;
37  }
38  // if (type_ == MTF7) {
39  // LogTrace("L1T") << "Writing MTF7 link header";
40  // return ((id_ & ID_mask) << ID_shift) | ((size_ & size_mask) << size_shift) | ((capID_ & capID_mask) << capID_shift);
41  // }
42  LogTrace("L1T") << "Writing meaningless link header";
43  return 0;
44  }
45 
46  BxBlocks
47  Block::getBxBlocks(unsigned int payloadWordsPerBx, bool bxHeader) const
48  {
49  BxBlocks bxBlocks;
50 
51  // For MP7 format
52  unsigned int wordsPerBx = payloadWordsPerBx;
53  if (bxHeader) {
54  ++wordsPerBx;
55  }
56  // Calculate how many BxBlock objects can be made with the available payload
57  unsigned int nBxBlocks = payload_.size() / wordsPerBx;
58  for (size_t bxCtr = 0; bxCtr < nBxBlocks; ++bxCtr) {
59  size_t startIdx = bxCtr * wordsPerBx;
60  auto startBxBlock = payload_.cbegin()+startIdx;
61  // Pick the words from the block payload that correspond to the BX and add a BxBlock to the BxBlocks
62  if (bxHeader) {
63  bxBlocks.emplace_back(startBxBlock, startBxBlock+wordsPerBx);
64  } else {
65  bxBlocks.emplace_back(bxCtr, nBxBlocks, startBxBlock, startBxBlock+wordsPerBx);
66  }
67  }
68 
69  return bxBlocks;
70  }
71 
72  std::unique_ptr<Block>
74  {
75  if (end_ - data_ < getHeaderSize()) {
76  LogDebug("L1T") << "Reached end of payload";
77  return std::auto_ptr<Block>();
78  }
79 
80  if (data_[0] == 0xffffffff) {
81  LogDebug("L1T") << "Skipping padding word";
82  ++data_;
83  return getBlock();
84  }
85 
86  auto header = getHeader();
87 
88  if (end_ - data_ < header.getSize()) {
89  edm::LogError("L1T")
90  << "Expecting a block size of " << header.getSize()
91  << " but only " << (end_ - data_) << " words remaining";
92  return std::auto_ptr<Block>();
93  }
94 
95  LogTrace("L1T") << "Creating block with size " << header.getSize();
96 
97  auto res = std::unique_ptr<Block>(new Block(header, data_, data_ + header.getSize()));
98  data_ += header.getSize();
99  return res;
100  }
101 
102  MP7Payload::MP7Payload(const uint32_t * data, const uint32_t * end, bool legacy_mc) : Payload(data, end)
103  {
104  // For legacy MC (74 first MC campaigns) skip one empty word that was
105  // reserved for the header. With data, read out infrastructure
106  // version and algorithm version.
107  if (legacy_mc) {
108  LogTrace("L1T") << "Skipping " << std::hex << *data_;
109  ++data_;
110  } else {
111  infra_ = data_[0];
112  algo_ = data_[1];
113  data_ += 2;
114  }
115  }
116 
119  {
120  LogTrace("L1T") << "Getting header from " << std::hex << std::setw(8) << *data_;
121 
122  return BlockHeader(data_++);
123  }
124 
125  MTF7Payload::MTF7Payload(const uint32_t * data, const uint32_t * end) : Payload(data, end)
126  {
127  const uint16_t * data16 = reinterpret_cast<const uint16_t*>(data);
128  const uint16_t * end16 = reinterpret_cast<const uint16_t*>(end);
129 
130  if (end16 - data16 < header_size + counter_size + trailer_size) {
131  edm::LogError("L1T") << "MTF7 payload smaller than allowed!";
132  data_ = end_;
133  } else if (
134  ((data16[0] >> 12) != 0x9) || ((data16[1] >> 12) != 0x9) ||
135  ((data16[2] >> 12) != 0x9) || ((data16[3] >> 12) != 0x9) ||
136  ((data16[4] >> 12) != 0xA) || ((data16[5] >> 12) != 0xA) ||
137  ((data16[6] >> 12) != 0xA) || ((data16[7] >> 12) != 0xA) ||
138  ((data16[8] >> 9) != 0b1000000) || ((data16[9] >> 11) != 0) ||
139  ((data16[10] >> 11) != 0) || ((data16[11] >> 11) != 0)) {
140  edm::LogError("L1T") << "MTF7 payload has invalid header!";
141  data_ = end_;
142  } else if (
143  ((data16[12] >> 15) != 0) || ((data16[13] >> 15) != 1) ||
144  ((data16[14] >> 15) != 0) || ((data16[15] >> 15) != 0)) {
145  edm::LogError("L1T") << "MTF7 payload has invalid counter block!";
146  data_ = end_;
147  } else if (
148  false) {
149  // TODO: check trailer
150  }
151  }
152 
153  int
154  MTF7Payload::count(unsigned int pattern, unsigned int length) const
155  {
156  unsigned int mask = 0;
157  for (; length > 0; length--)
158  mask = (mask << 4) | 0xf;
159 
160  int count = 0;
161  for (const auto& p: block_patterns_)
162  count += (p & mask) == pattern;
163  return count;
164  }
165 
166  bool
167  MTF7Payload::valid(unsigned int pattern) const
168  {
169  for (const auto& p: block_patterns_) {
170  if (p == pattern)
171  return true;
172  }
173  return false;
174  }
175 
176  std::unique_ptr<Block>
178  {
179  if (end_ - data_ < 2)
180  return std::auto_ptr<Block>(nullptr);
181 
182  const uint16_t * data16 = reinterpret_cast<const uint16_t*>(data_);
183  const uint16_t * end16 = reinterpret_cast<const uint16_t*>(end_);
184 
185  // Read in blocks equivalent to 64 bit words, trying to match the
186  // pattern of first bits to what is deemed valid.
187  std::vector<uint32_t> payload;
188  unsigned int pattern = 0;
189  unsigned int i = 0;
190  for (; i < max_block_length_ and data16 + (i + 1) * 4 <= end16; ++i) {
191  for (int j = 0; j < 4; ++j) {
192  auto n = i * 4 + j;
193  pattern |= (data16[n] >> 15) << n;
194  payload.push_back(data16[n]);
195  }
196 
197  if (count(pattern, i + 1) == 1 and valid(pattern))
198  break;
199  }
200 
201  if (not valid(pattern)) {
202  edm::LogWarning("L1T") << "MTF7 block with unrecognized id 0x" << std::hex << pattern;
203  return std::auto_ptr<Block>(nullptr);
204  }
205 
206  data_ += (i + 1) * 2;
207  return std::unique_ptr<Block>(new Block(pattern, payload, 0, MTF7));
208  }
209 
210  CTP7Payload::CTP7Payload(const uint32_t * data, const uint32_t * end, amc::Header amcHeader) : Payload(data, end), amcHeader_(amcHeader)
211  {
212  if (not (*data_ == 0xA110CA7E) ) {
213  edm::LogError("L1T") << "CTP7 block with invalid header:" << std::hex << *data_;
214  }
215  ++data_;
216  bx_per_l1a_ = (*data_ >> 16) & 0xff;
217  calo_bxid_ = *data_ & 0xfff;
218  capId_ = 0;
219  if (bx_per_l1a_ > 1) {
220  edm::LogInfo("L1T") << "CTP7 block with multiple bunch crossings:" << bx_per_l1a_;
221  }
223  infra_ = 0;
224  ++data_;
225  }
226 
229  {
230  // only one block type, use dummy id
231  unsigned blockId = 0;
232  // CTP7 header contains number of BX in payload and the bunch crossing ID
233  // Not sure how to map to generic BlockHeader variables, so just packing
234  // it all in flags variable
235  unsigned blockFlags = ((bx_per_l1a_&0xf)<<16) | (calo_bxid_&0xfff);
236  unsigned blockSize = 192;
237  return BlockHeader(blockId, blockSize, capId_, blockFlags, CTP7);
238  }
239 
240  std::unique_ptr<Block>
242  {
243  if (end_ - data_ < getHeaderSize()) {
244  LogDebug("L1T") << "Reached end of payload";
245  return std::auto_ptr<Block>();
246  }
247  if ( capId_ > bx_per_l1a_ ) {
248  edm::LogWarning("L1T") << "CTP7 with more bunch crossings than expected";
249  }
250 
251  auto header = getHeader();
252 
253  if (end_ - data_ < header.getSize()) {
254  edm::LogError("L1T")
255  << "Expecting a block size of " << header.getSize()
256  << " but only " << (end_ - data_) << " words remaining";
257  return std::auto_ptr<Block>();
258  }
259 
260  LogTrace("L1T") << "Creating block with size " << header.getSize();
261 
262  auto res = std::unique_ptr<Block>(new Block(header, data_, data_ + header.getSize()));
263  data_ += header.getSize();
264  capId_++;
265  return res;
266  }
267 }
#define LogDebug(id)
BlockHeader getHeader() override
Definition: Block.cc:228
static constexpr unsigned capID_shift
Definition: Block.h:36
MP7Payload(const uint32_t *data, const uint32_t *end, bool legacy_mc=false)
Definition: Block.cc:102
Definition: Block.h:11
static constexpr unsigned capID_mask
Definition: Block.h:37
static constexpr unsigned flags_mask
Definition: Block.h:39
static constexpr unsigned size_shift
Definition: Block.h:34
std::vector< l1t::Jet >::iterator end_
static constexpr unsigned max_block_length_
Definition: Block.h:116
unsigned getHeaderSize() const override
Definition: Block.h:126
static constexpr unsigned flags_shift
Definition: Block.h:38
static constexpr unsigned header_size
Definition: Block.h:110
delete x;
Definition: CaloConfig.h:22
int count(unsigned int pattern, unsigned int length) const
Definition: Block.cc:154
block_t type_
Definition: Block.h:45
const uint32_t * end_
Definition: Block.h:88
unsigned int flags_
Definition: Block.h:44
virtual std::unique_ptr< Block > getBlock()
Definition: Block.cc:73
Definition: Electron.h:6
unsigned capId_
Definition: Block.h:135
static constexpr unsigned counter_size
Definition: Block.h:111
bool valid(unsigned int pattern) const
Definition: Block.cc:167
static constexpr unsigned ID_mask
Definition: Block.h:33
#define end
Definition: vmac.h:39
unsigned infra_
Definition: Block.h:91
unsigned int size_
Definition: Block.h:42
#define LogTrace(id)
MTF7Payload(const uint32_t *data, const uint32_t *end)
Definition: Block.cc:125
unsigned int capID_
Definition: Block.h:43
const uint32_t * data_
Definition: Block.h:87
static constexpr unsigned size_mask
Definition: Block.h:35
std::vector< BxBlock > BxBlocks
Definition: BxBlock.h:68
unsigned calo_bxid_
Definition: Block.h:137
CTP7Payload(const uint32_t *data, const uint32_t *end, amc::Header amcHeader)
Definition: Block.cc:210
BlockHeader getHeader() override
Definition: Block.cc:118
static constexpr unsigned trailer_size
Definition: Block.h:112
unsigned int getUserData() const
Definition: AMCSpec.h:72
unsigned bx_per_l1a_
Definition: Block.h:136
BxBlocks getBxBlocks(unsigned int payloadWordsPerBx, bool bxHeader) const
Definition: Block.cc:47
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
unsigned int id_
Definition: Block.h:41
std::unique_ptr< Block > getBlock() override
Definition: Block.cc:241
static constexpr unsigned ID_shift
Definition: Block.h:32
amc::Header amcHeader_
Definition: Block.h:138
uint32_t raw() const
Definition: Block.cc:28
unsigned algo_
Definition: Block.h:90
static const std::vector< unsigned int > block_patterns_
Definition: Block.h:117
std::unique_ptr< Block > getBlock() override
Definition: Block.cc:177