CMS 3D CMS Logo

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