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