Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:53

0001 #ifndef UCTCTP7RawData_HCALFB_hh
0002 #define UCTCTP7RawData_HCALFB_hh
0003 
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0006 
0007 class UCTCTP7RawData_HCALFB {
0008 public:
0009   enum CaloType { EBEE = 0, HBHE, HF };
0010 
0011   // read-only constructor
0012   UCTCTP7RawData_HCALFB(const uint32_t* d) : myDataPtr(d) {
0013     if (myDataPtr == nullptr) {
0014       edm::LogError("UCTCTP7RawData_HCALFB") << "You gave me a nullptr :<";
0015     }
0016   }
0017   // read-write constructor, caller must allocate 220*sizeof(uint32_t) bytes
0018   UCTCTP7RawData_HCALFB(uint32_t* d) : myDataPtr(d), myDataWritePtr(d) {
0019     if (myDataPtr == nullptr) {
0020       edm::LogError("UCTCTP7RawData_HCALFB") << "You gave me a nullptr :<";
0021     }
0022   }
0023 
0024   // No copy constructor and equality operator are needed
0025   UCTCTP7RawData_HCALFB(const UCTCTP7RawData_HCALFB&) = delete;
0026   const UCTCTP7RawData_HCALFB& operator=(const UCTCTP7RawData_HCALFB& i) = delete;
0027 
0028   virtual ~UCTCTP7RawData_HCALFB() { ; }
0029 
0030   // Access functions for convenience
0031 
0032   const uint32_t* dataPtr() const { return myDataPtr; }
0033 
0034   uint32_t sof() { return myDataPtr[0]; }
0035 
0036   size_t getIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0037     size_t index = 0;
0038     if (cType == EBEE || cType == HBHE) {
0039       if (iPhi > 3) {
0040         edm::LogError("UCTCTP7RawData_HCALFB") << "Incorrect iPhi; iPhi = " << iPhi << "; should be in [0,3]";
0041         return index;
0042       }
0043       if (cEta < 1 || cEta > 28) {
0044         edm::LogError("UCTCTP7RawData_HCALFB") << "Incorrect caloEta; cEta = " << cEta << "; should be in [1-28]";
0045         return index;
0046       }
0047       // ECAL/HB+HE fragment size is 3/4 32-bit words
0048       // Each fragment covers 2 eta and 4 phi towers
0049       // All four phi towers are in one 32-bit word
0050       // Even and odd eta are in neighboring 32-bit words
0051       index = (((cEta - 1) / 2) * (3 + 4) + ((cEta - 1) % 2));
0052       // But, towers are arranged in a peculiar order for firmware
0053       // convenience - the index needs to be computing with these
0054       // if statements.  This is brittle code that one should be
0055       // very careful with.
0056       if (negativeEta) {
0057         // Add offset for 6 ECAL and 6 HCAL fragments
0058         index += (6 * (3 + 4));
0059       } else {
0060         if (cEta > 12) {
0061           // Add offset for 14 ECAL, 14 HB+HE and 2 HF fragments
0062           // Note that first six are included in the definition of
0063           // the variable - index
0064           // Note also that HF fragments are larger at 4 32-bit words
0065           index += ((14 * (3 + 4) + (2 * 4)));
0066         }
0067       }
0068       // Data starts with ECAL towers so offset by 3 additional 32-bit words
0069       if (cType == HBHE)
0070         index += 3;
0071     } else if (cType == HF) {
0072       if (iPhi > 1) {
0073         edm::LogError("UCTCTP7RawData_HCALFB") << "HF iPhi should be 0 or 1 (for a , b) - invalid iPhi  = " << iPhi;
0074         return index;
0075       }
0076       if (cEta < 30 || cEta > 41) {
0077         edm::LogError("UCTCTP7RawData_HCALFB") << "HF cEta should be between 30 and 41 - invalid cEta = " << cEta;
0078         return index;
0079       }
0080       if (negativeEta) {
0081         if (iPhi == 0) {
0082           // Offset by 6 positive eta and 14 negative eta EBEE/HBHE fragments (each 3/4 32-bit words)
0083           // There are four HF cEta towers packed in each 32-bit word
0084           // Add additional offset of 1 for (34-37) and 2 for (38-41)
0085           index = 20 * (3 + 4) + ((cEta - 30) / 4);
0086         } else {
0087           // Additional HF a fragment offset for HF b channel
0088           index = 20 * (3 + 4) + 1 * 4 + ((cEta - 30) / 4);
0089         }
0090       } else {
0091         if (iPhi == 0) {
0092           // Offset by all EBEE/HBHE and two HF fragments (4 32-bit words)
0093           index = 2 * 14 * (3 + 4) + 2 * 4 + ((cEta - 30) / 4);
0094         } else {
0095           // Additional HF a fragment offset for HF b channel
0096           index = 2 * 14 * (3 + 4) + 3 * 4 + ((cEta - 30) / 4);
0097         }
0098       }
0099     } else {
0100       edm::LogError("UCTCTP7RawData_HCALFB") << "Unknown CaloType " << cType;
0101       return index;
0102     }
0103     if (index >= 220) {
0104       edm::LogError("UCTCTP7RawData_HCALFB") << "Managed to calculate an out-of-bounds index, buyer beware";
0105     }
0106     return index;
0107   }
0108 
0109   size_t getFeatureIndex(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0110     // Get index into the data words for the tower
0111     size_t index = getIndex(cType, negativeEta, cEta, iPhi);
0112     if (cType == EBEE || cType == HBHE) {
0113       // Two 32-bit words contain ET, so we should offset the index to
0114       // to the feature and link status bits
0115       if (((cEta - 1) % 2) == 0) {
0116         // [index] is offset to ET of first four towers (0 - 3)
0117         // [index + 2] is where the feature and link status bits are
0118         index += 2;
0119       } else {
0120         // In this case [index] is offset to ET of second four towers (4 - 7)
0121         // [index + 1] is where the feature and link status bits are
0122         index += 1;
0123       }
0124     } else if (cType == HF) {
0125       // HF Fragment has different structure than EBEE and HBHE fragments
0126       // First three 32-bit words have ETs for 11 objects (yes, 11 not 12)
0127       // cEta = 40 / 41 are double in eta and flop bettween a and b HF fragments
0128       // Further the remaining upper byte of the third word actually has feature
0129       // bits.  This feature index will point to the 4th 32-bit word.  It is
0130       // expected that the top byte from 3rd 32-bit word will be patched in within
0131       // the feature bit access function.
0132       // Since there are three instead of if block as above for EBEE, HBHE
0133       // I wrote here a more compact implementation of index computation.
0134       index += (3 - ((cEta - 30) / 4));
0135       if (index == 0) {
0136         // Since we sticth index-1, zero is also illegal
0137         edm::LogError("UCTCTP7RawData_HCALFB") << "Managed to calculate an out-of-bounds index, buyer beware";
0138       }
0139     } else {
0140       // Unknown calotype error already generated in getIndex()
0141       return 0;
0142     }
0143     if (index >= 220) {
0144       edm::LogError("UCTCTP7RawData_HCALFB") << "Managed to calculate an out-of-bounds index, buyer beware";
0145     }
0146     return index;
0147   }
0148 
0149   void setET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi, uint32_t et) {
0150     if (myDataWritePtr == nullptr) {
0151       edm::LogError("UCTCTP7RawData_HCALFB") << "I was made in read-only mode";
0152       return;
0153     }
0154     size_t index = getIndex(cType, negativeEta, cEta, iPhi);
0155     uint32_t& data = myDataWritePtr[index];
0156     if (cType == HF) {
0157       // Pick out the correct 8-bits for the iEta chosen
0158       // Note that cEta = 41 is special, it only occurs for iPhi == 1 and shares cEta = 40 position
0159       if (cEta == 41) {
0160         data |= (et & 0xFF) << 16;
0161       } else {
0162         data |= (et & 0xFF) << (((cEta - 30) % 4) * 8);
0163       }
0164     } else {
0165       // Pick out the correct 8-bits for the iPhi chosen
0166       data |= (et & 0xFF) << (iPhi * 8);
0167     }
0168   }
0169 
0170   uint32_t getET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0171     size_t index = getIndex(cType, negativeEta, cEta, iPhi);
0172     const uint32_t data = myDataPtr[index];
0173     uint32_t et = 0xDEADBEEF;
0174     if (cType == HF) {
0175       // Pick out the correct 8-bits for the iEta chosen
0176       // Note that cEta = 41 is special, it only occurs for iPhi == 1 and shares cEta = 40 position
0177       if (cEta == 41)
0178         et = ((data >> 16) & 0xFF);
0179       else
0180         et = ((data >> ((cEta - 30) % 4) * 8) & 0xFF);
0181     } else {
0182       // Pick out the correct 8-bits for the iPhi chosen
0183       et = ((data >> (iPhi * 8)) & 0xFF);
0184     }
0185     return et;
0186   }
0187 
0188   void setFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi, uint32_t fb) {
0189     if (myDataWritePtr == nullptr) {
0190       edm::LogError("UCTCTP7RawData_HCALFB") << "I was made in read-only mode";
0191       return;
0192     }
0193     if (cType == HF) {
0194       setHFFeatureBits(negativeEta, cEta, iPhi, fb);
0195     } else {
0196       size_t index = getFeatureIndex(cType, negativeEta, cEta, iPhi);
0197       uint32_t& data = myDataWritePtr[index];
0198 
0199       uint32_t tower = iPhi;
0200       if (((cEta - 1) % 2) == 1) {
0201         tower += 4;
0202       }
0203       if (cType == HBHE) {
0204         int depth = fb & 0b1;
0205         int prompt = (fb & 0b10) >> 1;
0206         int delay1 = (fb & 0b100) >> 2;
0207         int delay2 = (fb & 0b1000) >> 3;
0208         if (cEta < 16)
0209           data |= (depth | ((!prompt) & (delay1 | delay2))) << tower;  // bit[0] | (!bit[1] & (bit[2] | bit[3]))
0210       } else
0211         data |= (fb & 0x1) << tower;
0212     }
0213   }
0214 
0215   uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0216     size_t index = getFeatureIndex(cType, negativeEta, cEta, iPhi);
0217     if (cType == HBHE) {
0218       if (((cEta - 1) % 2) == 1) {
0219         index += 1;
0220       }
0221     }
0222     const uint32_t data = myDataPtr[index];
0223     uint32_t fb = 0;
0224     if (cType == HF) {
0225       fb = getHFFeatureBits(negativeEta, cEta, iPhi);
0226     } else if (cType == EBEE) {
0227       // Pick out the correct bit for the tower chosen
0228       uint32_t tower = iPhi;
0229       if (((cEta - 1) % 2) == 1) {
0230         tower += 4;
0231       }
0232       fb = ((data & (0x1 << tower)) != 0) ? 1 : 0;
0233     } else {
0234       fb = ((data >> (iPhi * 6)) & 0x3F);
0235     }
0236     return fb;
0237   }
0238 
0239   void setHFFeatureBits(bool negativeEta, uint32_t cEta, uint32_t iPhi, uint32_t fb) {
0240     if (myDataWritePtr == nullptr) {
0241       edm::LogError("UCTCTP7RawData_HCALFB") << "I was made in read-only mode";
0242       return;
0243     }
0244     size_t index = getFeatureIndex(HF, negativeEta, cEta, iPhi);
0245     uint32_t shift = (cEta - 30) * 2;
0246     if (cEta == 41)
0247       shift = 20;  // 41 occurs on b-fiber but shares the position of 40
0248     if (shift >= 8) {
0249       uint32_t& data = myDataWritePtr[index];
0250       data |= (fb & 0x3) << (shift - 8);
0251     } else {
0252       uint32_t& data = myDataWritePtr[index - 1];
0253       data |= (fb & 0x3) << (shift + 24);
0254     }
0255   }
0256 
0257   uint32_t getHFFeatureBits(bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0258     size_t index = getFeatureIndex(HF, negativeEta, cEta, iPhi);
0259     // Stitch together the top 8 bits from previous 32-bit word and bottom 14 bits from this word
0260     const uint32_t data = ((myDataPtr[index] & 0x3FFF) << 8) + (myDataPtr[index - 1] >> 24);
0261     uint32_t shift = (cEta - 30) * 2;
0262     if (cEta == 41)
0263       shift = 20;  // 41 occurs on b-fiber but shares the position of 40
0264     return ((data >> shift) & 0x3);
0265   }
0266 
0267   uint32_t getLinkStatus(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0268     size_t index = getFeatureIndex(cType, negativeEta, cEta, iPhi);
0269     const uint32_t data = myDataPtr[index];
0270     const uint32_t data2 = myDataPtr[index + 1];
0271     uint32_t LS = 0;
0272     if (cType == HBHE) {
0273       LS = (data >> 24) & 0xFF;
0274       LS |= ((data2 >> 24) & 0xFF) << 8;
0275     } else {
0276       LS = (data >> 16);
0277     }
0278     return LS;
0279   }
0280 
0281   size_t getSummaryIndex(bool negativeEta, uint32_t region) {
0282     size_t index = 2 * 14 * (3 + 4) + 4 * 4 + (region / 2);
0283     if (negativeEta)
0284       index += 4;
0285     if (index >= 220) {
0286       edm::LogError("UCTCTP7RawData_HCALFB") << "Managed to calculate an out-of-bounds index, buyer beware";
0287     }
0288     return index;
0289   }
0290 
0291   void setRegionSummary(bool negativeEta, uint32_t region, uint32_t regionData) {
0292     if (myDataWritePtr == nullptr) {
0293       edm::LogError("UCTCTP7RawData_HCALFB") << "I was made in read-only mode";
0294       return;
0295     }
0296     size_t index = getSummaryIndex(negativeEta, region);
0297     uint32_t& data = myDataWritePtr[index];
0298     data |= (regionData & 0xFFFF) << (16 * (region % 2));
0299   }
0300 
0301   uint32_t getRegionSummary(bool negativeEta, uint32_t region) {
0302     size_t index = getSummaryIndex(negativeEta, region);
0303     const uint32_t data = myDataPtr[index];
0304     return ((data >> (16 * (region % 2))) & 0xFFFF);
0305   }
0306 
0307   uint32_t getRegionET(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x3FF); }
0308 
0309   bool getRegionEGVeto(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x0400); }
0310 
0311   bool getRegionTauVeto(bool negativeEta, uint32_t region) { return (getRegionSummary(negativeEta, region) & 0x0800); }
0312 
0313   uint32_t getRegionHitLocation(bool negativeEta, uint32_t region) {
0314     return ((getRegionSummary(negativeEta, region) & 0xF000) >> 12);
0315   }
0316 
0317   bool isTowerMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0318     uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
0319     uint32_t tower = iPhi;
0320     if ((cEta % 2) == 0)
0321       tower += 4;
0322     if (cType == HF) {
0323       tower = (cEta - 30);
0324       if (cEta == 41)
0325         tower = 10;
0326     }
0327     return ((linkStatus & (0x1 << tower)) != 0);
0328   }
0329 
0330   bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0331     uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
0332     if (cType == EBEE && (cEta == 17 || cEta == 21)) {
0333       return ((linkStatus & 0x00000100) != 0);
0334     }
0335     return ((linkStatus & 0x00001000) != 0);
0336   }
0337 
0338   bool isLinkInError(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0339     uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
0340     if (cType == EBEE && (cEta == 17 || cEta == 21)) {
0341       return ((linkStatus & 0x00000200) != 0);
0342     }
0343     return ((linkStatus & 0x00002000) != 0);
0344   }
0345 
0346   bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0347     uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
0348     if (cType == EBEE && (cEta == 17 || cEta == 21)) {
0349       return ((linkStatus & 0x00000400) != 0);
0350     }
0351     return ((linkStatus & 0x00004000) != 0);
0352   }
0353 
0354   bool isLinkMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi) {
0355     uint32_t linkStatus = getLinkStatus(cType, negativeEta, cEta, iPhi);
0356     if (cType == EBEE && (cEta == 17 || cEta == 21)) {
0357       return ((linkStatus & 0x00000800) != 0);
0358     }
0359     return ((linkStatus & 0x00008000) != 0);
0360   }
0361 
0362 private:
0363   // Pointer to contiguous array of 220 values
0364   // We assume instantiator of this class will gurantee that fact
0365   const uint32_t* myDataPtr;
0366   // == myDataPtr unless read-only
0367   uint32_t* myDataWritePtr = nullptr;
0368 };
0369 
0370 #endif