Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-26 01:51:02

0001 #ifndef DataFormats_L1TCalorimeterPhase2_DigitizedClusterCorrelator_h
0002 #define DataFormats_L1TCalorimeterPhase2_DigitizedClusterCorrelator_h
0003 
0004 #include <ap_int.h>
0005 #include <vector>
0006 
0007 namespace l1tp2 {
0008 
0009   class DigitizedClusterCorrelator {
0010   private:
0011     // Data
0012     unsigned long long int clusterData;
0013     unsigned int idxGCTCard;  // 0, 1, or 2
0014 
0015     // Constants
0016     static constexpr unsigned int n_towers_eta = 34;  // in GCT card unique region
0017     static constexpr unsigned int n_towers_phi = 24;  // in GCT card unique region
0018     static constexpr unsigned int n_crystals_in_tower = 5;
0019     static constexpr float LSB_PT = 0.5;                 // 0.5 GeV
0020     static constexpr float ETA_RANGE_ONE_SIDE = 1.4841;  // barrel goes from (-1.4841, +1.4841)
0021     static constexpr float LSB_ETA = ((2 * ETA_RANGE_ONE_SIDE) / (n_towers_eta * n_crystals_in_tower));  // (2.8 / 170)
0022     static constexpr float LSB_PHI = ((2 * M_PI) / (3 * n_towers_phi * n_crystals_in_tower));            // (2 pi * 360)
0023 
0024     static constexpr unsigned int n_bits_pt = 12;            // 12 bits allocated for pt
0025     static constexpr unsigned int n_bits_unused_start = 63;  // unused bits start at bit 63
0026 
0027     // "top" of the correlator card #0 in GCT coordinates is iPhi tower index 24
0028     static constexpr int correlatorCard0_tower_iphi_offset = 24;
0029     // same but for correlator cards #1 and 2 (cards wrap around phi = 180 degrees):
0030     static constexpr int correlatorCard1_tower_iphi_offset = 48;
0031     static constexpr int correlatorCard2_tower_iphi_offset = 0;
0032 
0033     // Private member functions to perform digitization
0034     ap_uint<12> digitizePt(float pt_f) {
0035       float maxPt_f = (std::pow(2, n_bits_pt) - 1) * LSB_PT;
0036       // If pT exceeds the maximum (extremely unlikely), saturate the value
0037       if (pt_f >= maxPt_f) {
0038         return (ap_uint<12>)0xFFF;
0039       }
0040 
0041       return (ap_uint<12>)(pt_f / LSB_PT);
0042     }
0043 
0044     ap_uint<8> digitizeIEtaCr(unsigned int iEtaCr) { return (ap_uint<8>)iEtaCr; }
0045 
0046     ap_uint<7> digitizeIPhiCr(unsigned int iPhiCr) { return (ap_uint<7>)iPhiCr; }
0047 
0048     // To-do: HoE is not defined for clusters
0049     ap_uint<4> digitizeHoE(unsigned int hoe) { return (ap_uint<4>)hoe; }
0050     ap_uint<2> digitizeHoeFlag(unsigned int hoeFlag) { return (ap_uint<2>)hoeFlag; }
0051 
0052     ap_uint<3> digitizeIso(unsigned int iso) { return (ap_uint<3>)iso; }
0053     ap_uint<2> digitizeIsoFlag(unsigned int isoFlag) { return (ap_uint<2>)isoFlag; }
0054 
0055     // To-do: fb: no information yet
0056     ap_uint<6> digitizeFb(unsigned int fb) { return (ap_uint<6>)fb; }
0057 
0058     // To-do: timing: no information yet
0059     ap_uint<5> digitizeTiming(unsigned int timing) { return (ap_uint<5>)timing; }
0060 
0061     // Shape: shower shape working point
0062     ap_uint<2> digitizeShapeFlag(unsigned int shapeFlag) { return (ap_uint<2>)shapeFlag; }
0063 
0064     // TO-DO: Brems: was brems applied (NOT STORED YET IN GCT)
0065     ap_uint<2> digitizeBrems(unsigned int brems) { return (ap_uint<2>)brems; }
0066 
0067   public:
0068     DigitizedClusterCorrelator() { clusterData = 0x0; }
0069 
0070     DigitizedClusterCorrelator(ap_uint<64> data) { clusterData = data; }
0071 
0072     // Constructor from digitized inputs
0073     DigitizedClusterCorrelator(ap_uint<12> pt,
0074                                ap_uint<8> etaCr,
0075                                ap_uint<7> phiCr,
0076                                ap_uint<4> hoe,
0077                                ap_uint<2> hoeFlag,
0078                                ap_uint<3> iso,
0079                                ap_uint<2> isoFlag,
0080                                ap_uint<6> fb,
0081                                ap_uint<5> timing,
0082                                ap_uint<2> shapeFlag,
0083                                ap_uint<2> brems,
0084                                int iGCTCard,
0085                                bool fullydigitizedInputs) {
0086       (void)fullydigitizedInputs;
0087       clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)etaCr) << 12) | (((ap_uint<64>)phiCr) << 20) |
0088                     (((ap_uint<64>)hoe) << 27) | (((ap_uint<64>)hoeFlag) << 31) | (((ap_uint<64>)iso) << 36) |
0089                     (((ap_uint<64>)isoFlag) << 38) | (((ap_uint<64>)fb) << 44) | (((ap_uint<64>)timing) << 49) |
0090                     (((ap_uint<64>)shapeFlag << 51)) | (((ap_uint<64>)brems << 53));
0091       idxGCTCard = iGCTCard;
0092     }
0093 
0094     // Constructor from float inputs
0095     DigitizedClusterCorrelator(float pt_f,
0096                                unsigned int iEtaCr,
0097                                unsigned int iPhiCr,
0098                                unsigned int hoe,
0099                                unsigned int hoeFlag,
0100                                unsigned int iso,
0101                                unsigned int isoFlag,
0102                                unsigned int fb,
0103                                unsigned int timing,
0104                                unsigned int shapeFlag,
0105                                unsigned int brems,
0106                                int iGCTCard) {
0107       clusterData = (((ap_uint<64>)digitizePt(pt_f)) | ((ap_uint<64>)digitizeIEtaCr(iEtaCr) << 12) |
0108                      ((ap_uint<64>)digitizeIPhiCr(iPhiCr) << 20) | ((ap_uint<64>)digitizeHoE(hoe) << 27) |
0109                      ((ap_uint<64>)digitizeHoeFlag(hoeFlag) << 31) | ((ap_uint<64>)digitizeIso(iso) << 36) |
0110                      ((ap_uint<64>)digitizeIsoFlag(isoFlag) << 38) | ((ap_uint<64>)digitizeFb(fb) << 44) |
0111                      ((ap_uint<64>)digitizeTiming(timing) << 49) | ((ap_uint<64>)digitizeShapeFlag(shapeFlag) << 51) |
0112                      ((ap_uint<64>)digitizeBrems(brems) << 53));
0113       idxGCTCard = iGCTCard;
0114     }
0115 
0116     ap_uint<64> data() const { return clusterData; }
0117 
0118     // Other getters
0119     float ptLSB() const { return LSB_PT; }
0120     ap_uint<12> pt() const { return (clusterData & 0xFFF); }
0121     float ptFloat() const { return (pt() * ptLSB()); }
0122 
0123     // crystal eta in the correlator region (LSB: 2.8/170)
0124     ap_uint<8> eta() const { return ((clusterData >> 12) & 0xFF); }  // (eight 1's) 0b11111111 = 0xFF
0125 
0126     // crystal phi in the correlator region (LSB: 2pi/360)
0127     ap_uint<7> phi() const { return ((clusterData >> 20) & 0x7F); }  // (seven 1's) 0b1111111 = 0x7F
0128 
0129     // HoE value and flag: not defined yet in the emulator
0130     ap_uint<4> hoe() const { return ((clusterData >> 27) & 0xF); }      // (four 1's) 0b1111 = 0xF
0131     ap_uint<2> hoeFlag() const { return ((clusterData >> 31) & 0x3); }  // (two 1's) 0b11 = 0x3
0132 
0133     // Raw isolation sum: not saved in the emulator
0134     ap_uint<3> iso() const { return ((clusterData >> 36) & 0x7); }
0135 
0136     // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false)
0137     // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass
0138     ap_uint<2> isoFlags() const { return ((clusterData >> 38) & 0x3); }  // (two 1's) 0b11 = 0x3
0139     bool passes_iso() const { return (isoFlags() & 0x1); }               // standalone iso WP
0140     bool passes_looseTkiso() const { return (isoFlags() & 0x2); }        // loose Tk iso WP
0141 
0142     // fb and timing: not saved in the current emulator
0143     ap_uint<6> fb() const { return ((clusterData >> 44) & 0x3F); }
0144     ap_uint<5> timing() const { return ((clusterData >> 49) & 0x1F); }
0145 
0146     // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP
0147     // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass
0148     ap_uint<2> shapeFlags() const { return ((clusterData >> 51) & 0x3); }
0149 
0150     bool passes_ss() const { return (shapeFlags() & 0x1); }         // standalone shower shape WP
0151     bool passes_looseTkss() const { return (shapeFlags() & 0x2); }  // loose Tk shower shape WP
0152 
0153     // brems: not saved in the current emulator
0154     ap_uint<2> brems() const { return ((clusterData >> 53) & 0x3); }
0155 
0156     // which GCT card (0, 1, or 2)
0157     unsigned int cardNumber() const { return idxGCTCard; }
0158 
0159     const int unusedBitsStart() const { return n_bits_unused_start; }
0160 
0161     // Other checks
0162     bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); }
0163 
0164     // Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841.
0165     // LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta
0166     float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA) + (LSB_ETA / 2)); }
0167 
0168     // Get real phi (uses card number).
0169     float realPhi() const {
0170       // each card starts at a different real phi
0171       int offset_tower = 0;
0172       if (cardNumber() == 0) {
0173         offset_tower = correlatorCard0_tower_iphi_offset;
0174       } else if (cardNumber() == 1) {
0175         offset_tower = correlatorCard1_tower_iphi_offset;
0176       } else if (cardNumber() == 2) {
0177         offset_tower = correlatorCard2_tower_iphi_offset;
0178       }
0179       int thisPhi = (phi() + (offset_tower * n_crystals_in_tower));
0180       // crystal iPhi = 0 starts at real phi = -180 degrees
0181       // LSB_PHI/2 is to add half a crystal width to get the center of the crystal in phi
0182       return (float)((-1 * M_PI) + (thisPhi * LSB_PHI) + (LSB_PHI / 2));
0183     }
0184   };
0185 
0186   // Collection typedef
0187   typedef std::vector<l1tp2::DigitizedClusterCorrelator> DigitizedClusterCorrelatorCollection;
0188 
0189 }  // namespace l1tp2
0190 
0191 #endif