CMS 3D CMS Logo

UCTCTP7RawData.h
Go to the documentation of this file.
1 #ifndef UCTCTP7RawData_hh
2 #define UCTCTP7RawData_hh
3 
6 
7 class UCTCTP7RawData {
8 public:
9  enum CaloType { EBEE = 0, HBHE, HF };
10 
11  UCTCTP7RawData(const uint32_t* d) : myDataPtr(d) {
12  if (myDataPtr != nullptr) {
13  if (sof() != 0xA110CA7E) {
14  edm::LogError("UCTCTP7RawData") << "Failed to see 0xA110CA7E at start - but continuing" << std::endl;
15  }
16  }
17  }
18 
19  // No copy constructor and equality operator are needed
20  UCTCTP7RawData(const UCTCTP7RawData&) = delete;
21  const UCTCTP7RawData& operator=(const UCTCTP7RawData& i) = delete;
22 
23  virtual ~UCTCTP7RawData() { ; }
24 
25  // Access functions for convenience
26 
27  const uint32_t* dataPtr() const { return myDataPtr; }
28 
29  uint32_t sof() { return myDataPtr[0]; }
30 
31  uint32_t caloLinkBXID() { return (myDataPtr[1] & 0x00000FFF); }
32 
33  uint32_t nBXPerL1A() { return ((myDataPtr[1] & 0x000F0000) >> 16); }
34 
35  uint32_t getIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
36  uint32_t index = 0xDEADBEEF;
37  if (cType == EBEE || cType == HBHE) {
38  if (iPhi > 3) {
39  edm::LogError("UCTCTP7RawData") << "Incorrect iPhi; iPhi = " << iPhi << "; should be in [0,3]" << std::endl;
40  return 0xDEADBEEF;
41  }
42  if (cEta < 1 || cEta > 28) {
43  edm::LogError("UCTCTP7RawData") << "Incorrect caloEta; cEta = " << cEta << "; should be in [1-28]" << std::endl;
44  return 0xDEADBEEF;
45  }
46  // ECAL/HB+HE fragment size is 3 32-bit words
47  // Each fragment covers 2 eta and 4 phi towers
48  // All four phi towers are in one 32-bit word
49  // Even and odd eta are in neighboring 32-bit words
50  index = 2 + (((cEta - 1) / 2) * (3 + 3) + ((cEta - 1) % 2));
51  // But, towers are arranged in a peculiar order for firmware
52  // convenience - the index needs to be computing with these
53  // if statements. This is brittle code that one should be
54  // very careful with.
55  if (negativeEta) {
56  // Add offset for 6 ECAL and 6 HCAL fragments
57  index += (6 * (3 + 3));
58  } else {
59  if (cEta > 12) {
60  // Add offset for 14 ECAL, 14 HB+HE and 2 HF fragments
61  // Note that first six are included in the definition of
62  // the variable - index
63  // Note also that HF fragments are larger at 4 32-bit words
64  index += ((14 * (3 + 3) + (2 * 4)));
65  }
66  }
67  // Data starts with ECAL towers so offset by 3 additional 32-bit words
68  if (cType == HBHE)
69  index += 3;
70  } else if (cType == HF) {
71  if (iPhi > 1) {
72  edm::LogError("UCTCTP7RawData") << "HF iPhi should be 0 or 1 (for a , b) - invalid iPhi = " << iPhi
73  << std::endl;
74  return 0xDEADBEEF;
75  }
76  if (cEta < 30 || cEta > 41) {
77  edm::LogError("UCTCTP7RawData") << "HF cEta should be between 30 and 41 - invalid cEta = " << cEta << std::endl;
78  return 0xDEADBEEF;
79  }
80  if (negativeEta) {
81  if (iPhi == 0) {
82  // Offset by 6 positive eta and 14 negative eta EBEE/HBHE fragments (each 3 32-bit words)
83  // There are four HF cEta towers packed in each 32-bit word
84  // Add additional offset of 1 for (34-37) and 2 for (38-41)
85  index = 2 + 20 * (3 + 3) + ((cEta - 30) / 4);
86  } else {
87  // Additional HF a fragment offset for HF b channel
88  index = 2 + 20 * (3 + 3) + 1 * 4 + ((cEta - 30) / 4);
89  }
90  } else {
91  if (iPhi == 0) {
92  // Offset by all EBEE/HBHE and two HF fragments (4 32-bit words)
93  index = 2 + 2 * 14 * (3 + 3) + 2 * 4 + ((cEta - 30) / 4);
94  } else {
95  // Additional HF a fragment offset for HF b channel
96  index = 2 + 2 * 14 * (3 + 3) + 3 * 4 + ((cEta - 30) / 4);
97  }
98  }
99  } else {
100  edm::LogError("UCTCTP7RawData") << "Unknown CaloType " << cType << std::endl;
101  return 0xDEADBEEF;
102  }
103  return index;
104  }
105 
106  uint32_t getFeatureIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
107  // Get index into the data words for the tower
108  uint32_t index = getIndex(cType, negativeEta, cEta, iPhi);
109  if (cType == EBEE || cType == HBHE) {
110  // Two 32-bit words contain ET, so we should offset the index to
111  // to the feature and link status bits
112  if (((cEta - 1) % 2) == 0) {
113  // [index] is offset to ET of first four towers (0 - 3)
114  // [index + 2] is where the feature and link status bits are
115  index += 2;
116  } else {
117  // In this case [index] is offset to ET of second four towers (4 - 7)
118  // [index + 1] is where the feature and link status bits are
119  index += 1;
120  }
121  } else if (cType == HF) {
122  // HF Fragment has different structure than EBEE and HBHE fragments
123  // First three 32-bit words have ETs for 11 objects (yes, 11 not 12)
124  // cEta = 40 / 41 are double in eta and flop bettween a and b HF fragments
125  // Further the remaining upper byte of the third word actually has feature
126  // bits. This feature index will point to the 4th 32-bit word. It is
127  // expected that the top byte from 3rd 32-bit word will be patched in within
128  // the feature bit access function.
129  // Since there are three instead of if block as above for EBEE, HBHE
130  // I wrote here a more compact implementation of index computation.
131  index += (3 - ((cEta - 30) / 4));
132  } else {
133  return 0xDEADBEEF;
134  }
135  return index;
136  }
137 
138  uint32_t getET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
139  uint32_t index = getIndex(cType, negativeEta, cEta, iPhi);
140  const uint32_t data = myDataPtr[index];
141  uint32_t et = 0xDEADBEEF;
142  if (cType == HF) {
143  // Pick out the correct 8-bits for the iEta chosen
144  // Note that cEta = 41 is special, it only occurs for iPhi == 1 and shares cEta = 40 position
145  if (cEta == 41)
146  et = ((data >> 16) & 0xFF);
147  else
148  et = ((data >> ((cEta - 30) % 4) * 8) & 0xFF);
149  } else {
150  // Pick out the correct 8-bits for the iPhi chosen
151  et = ((data >> (iPhi * 8)) & 0xFF);
152  }
153  return et;
154  }
155 
156  uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
157  uint32_t index = getFeatureIndex(cType, negativeEta, cEta, iPhi);
158  const uint32_t data = myDataPtr[index];
159  uint32_t fb = 0;
160  if (cType == HF) {
161  fb = getHFFeatureBits(negativeEta, cEta, iPhi);
162  } else {
163  // Pick out the correct bit for the tower chosen
164  uint32_t tower = iPhi;
165  if (((cEta - 1) % 2) == 1) {
166  tower += 4;
167  }
168  fb = ((data & (0x1 << tower)) != 0) ? 1 : 0;
169  }
170  return fb;
171  }
172 
173  uint32_t getHFFeatureBits(bool negativeEta, uint32_t cEta, uint32_t iPhi) {
174  uint32_t index = getFeatureIndex(HF, negativeEta, cEta, iPhi);
175  // Stitch together the top 8 bits from previous 32-bit word and bottom 14 bits from this word
176  const uint32_t data = ((myDataPtr[index] & 0x3FFF) << 8) + (myDataPtr[index - 1] >> 24);
177  uint32_t shift = (cEta - 30) * 2;
178  if (cEta == 41)
179  shift = 20; // 41 occurs on b-fiber but shares the position of 40
180  return ((data >> shift) & 0x3);
181  }
182 
183  uint32_t getLinkStatus(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
184  uint32_t index = getFeatureIndex(cType, negativeEta, cEta, iPhi);
185  const uint32_t data = myDataPtr[index];
186  return (data >> 16);
187  }
188 
189  uint32_t getSummaryIndex(bool negativeEta, uint32_t region) {
190  uint32_t index = 2 + 2 * 14 * (3 + 3) + 4 * 4 + (region / 2);
191  if (negativeEta)
192  index += 4;
193  return index;
194  }
195 
196  uint32_t getRegionSummary(bool negativeEta, uint32_t region) {
197  uint32_t index = getSummaryIndex(negativeEta, region);
198  const uint32_t data = myDataPtr[index];
199  return ((data >> (16 * (region % 2))) & 0xFFFF);
200  }
201 
202  uint32_t getRegionET(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x3FF); }
203 
204  bool getRegionEGVeto(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x0400); }
205 
206  bool getRegionTauVeto(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x0800); }
207 
208  uint32_t getRegionHitLocation(bool negativeEta, uint32_t region) {
209  return ((getRegionSummary(negativeEta, region) & 0xF000) >> 12);
210  }
211 
212  bool isTowerMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
213  uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
214  uint32_t tower = iPhi;
215  if (((cEta - 1) % 2) == 1)
216  tower += 4;
217  if (cType == HF) {
218  tower = (cEta - 30);
219  if (cEta == 41)
220  tower = 10;
221  }
222  return ((linkStatus & (0x1 << tower)) != 0);
223  }
224 
225  bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
226  uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
227  if (cType == EBEE && (cEta == 17 || cEta == 21)) {
228  return ((linkStatus & 0x00000100) != 0);
229  }
230  return ((linkStatus & 0x00001000) != 0);
231  }
232 
233  bool isLinkInError(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
234  uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
235  if (cType == EBEE && (cEta == 17 || cEta == 21)) {
236  return ((linkStatus & 0x00000200) != 0);
237  }
238  return ((linkStatus & 0x00002000) != 0);
239  }
240 
241  bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
242  uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
243  if (cType == EBEE && (cEta == 17 || cEta == 21)) {
244  return ((linkStatus & 0x00000400) != 0);
245  }
246  return ((linkStatus & 0x00004000) != 0);
247  }
248 
249  bool isLinkMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
250  uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
251  if (cType == EBEE && (cEta == 17 || cEta == 21)) {
252  return ((linkStatus & 0x00000800) != 0);
253  }
254  return ((linkStatus & 0x00008000) != 0);
255  }
256 
257  void print() {
258  using namespace std;
259  edm::LogError("UCTCTP7RawData") << "CTP7 Payload Header:" << endl;
260  edm::LogError("UCTCTP7RawData") << "No BX per L1A = " << dec << nBXPerL1A() << endl;
261  edm::LogError("UCTCTP7RawData") << "Calo BX ID = " << dec << caloLinkBXID() << endl;
262  CaloType cType = EBEE;
263  bool negativeEta = false;
264  bool first = true;
265  for (uint32_t i = 0; i < 2; i++) {
266  if (i != 0)
267  negativeEta = true;
268  first = true;
269  cType = EBEE;
270  for (uint32_t cEta = 1; cEta <= 28; cEta++) {
271  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {
272  if (getLinkStatus(cType, negativeEta, cEta, iPhi) != 0 || getET(cType, negativeEta, cEta, iPhi) != 0) {
273  if (first)
274  edm::LogError("UCTCTP7RawData") << "EcalET FG LinkStatus" << endl;
275  first = false;
276  edm::LogError("UCTCTP7RawData")
277  << dec << setfill(' ') << setw(6) << getET(cType, negativeEta, cEta, iPhi) << " "
278  << getFB(cType, negativeEta, cEta, iPhi) << " " << showbase << internal << setfill('0') << setw(10)
279  << hex << getLinkStatus(cType, negativeEta, cEta, iPhi) << " (" << dec
280  << getIndex(cType, negativeEta, cEta, iPhi) << ", " << negativeEta << ", " << cEta << ", " << iPhi
281  << ")" << endl;
282  }
283  }
284  }
285  first = true;
286  cType = HBHE;
287  for (uint32_t cEta = 1; cEta <= 28; cEta++) {
288  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {
289  if (getLinkStatus(cType, negativeEta, cEta, iPhi) != 0 || getET(cType, negativeEta, cEta, iPhi) != 0) {
290  if (first)
291  edm::LogError("UCTCTP7RawData") << "HcalET Feature LinkStatus" << endl;
292  first = false;
293  edm::LogError("UCTCTP7RawData")
294  << dec << setfill(' ') << setw(6) << getET(cType, negativeEta, cEta, iPhi) << " "
295  << getFB(cType, negativeEta, cEta, iPhi) << " " << showbase << internal << setfill('0') << setw(10)
296  << hex << getLinkStatus(cType, negativeEta, cEta, iPhi) << " (" << dec
297  << getIndex(cType, negativeEta, cEta, iPhi) << ", " << negativeEta << ", " << cEta << ", " << iPhi
298  << ")" << endl;
299  }
300  }
301  }
302  first = true;
303  cType = HF;
304  for (uint32_t cEta = 30; cEta <= 40; cEta++) {
305  for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
306  if (iPhi == 1 && cEta == 40)
307  cEta = 41;
308  if (getLinkStatus(cType, negativeEta, cEta, iPhi) != 0 || getET(cType, negativeEta, cEta, iPhi) != 0) {
309  if (first)
310  edm::LogError("UCTCTP7RawData") << "HF-ET Feature LinkStatus" << endl;
311  first = false;
312  edm::LogError("UCTCTP7RawData")
313  << dec << setfill(' ') << setw(6) << getET(cType, negativeEta, cEta, iPhi) << " " << dec
314  << setfill(' ') << setw(2) << getHFFeatureBits(negativeEta, cEta, iPhi) << " " << showbase << internal
315  << setfill('0') << setw(10) << hex << getLinkStatus(cType, negativeEta, cEta, iPhi) << " (" << dec
316  << getIndex(cType, negativeEta, cEta, iPhi) << ", " << negativeEta << ", " << cEta << ", " << iPhi
317  << ")" << endl;
318  }
319  }
320  }
321  first = true;
322  for (uint32_t region = 0; region < 7; region++) {
323  if (first)
324  edm::LogError("UCTCTP7RawData") << "Region ET EGVeto TauVeto HitLocation" << endl;
325  first = false;
326  edm::LogError("UCTCTP7RawData") << dec << setfill(' ') << setw(6) << region << " " << hex << showbase
327  << internal << setfill('0') << setw(6) << getRegionET(negativeEta, region)
328  << dec << " " << getRegionEGVeto(negativeEta, region) << " "
329  << getRegionTauVeto(negativeEta, region) << " " << showbase << internal
330  << setfill('0') << setw(3) << hex << getRegionHitLocation(negativeEta, region)
331  << endl;
332  }
333  }
334  }
335 
336 private:
337  // RawData data
338 
339  const uint32_t* myDataPtr;
340 };
341 
342 #endif
uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool getRegionTauVeto(bool negativeEta, uint32_t region)
uint32_t getSummaryIndex(bool negativeEta, uint32_t region)
uint32_t getHFFeatureBits(bool negativeEta, uint32_t cEta, uint32_t iPhi)
uint32_t caloLinkBXID()
bool isLinkMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
size_t getFeatureIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
const UCTCTP7RawData & operator=(const UCTCTP7RawData &i)=delete
uint32_t sof()
Log< level::Error, false > LogError
bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool getRegionEGVeto(bool negativeEta, uint32_t region)
uint32_t nBXPerL1A()
bool isLinkInError(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool isTowerMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
const uint32_t * dataPtr() const
d
Definition: ztail.py:151
const uint32_t * myDataPtr
uint32_t getLinkStatus(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
uint32_t getIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
UCTCTP7RawData(const uint32_t *d)
size_t getSummaryIndex(bool negativeEta, uint32_t region)
uint32_t getRegionET(bool negativeEta, uint32_t region)
uint32_t getET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
size_t getIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
static unsigned int const shift
virtual ~UCTCTP7RawData()
uint32_t getRegionSummary(bool negativeEta, uint32_t region)
uint32_t getRegionHitLocation(bool negativeEta, uint32_t region)
uint32_t getFeatureIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)