CMS 3D CMS Logo

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