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