Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-10 01:50:14

0001 #ifndef DataFormats_L1TParticleFlow_datatypes_h
0002 #define DataFormats_L1TParticleFlow_datatypes_h
0003 
0004 #if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH)
0005 #pragma GCC diagnostic push
0006 #pragma GCC diagnostic ignored "-Wint-in-bool-context"
0007 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0008 #pragma GCC diagnostic ignored "-Wuninitialized"
0009 #endif
0010 #include <ap_int.h>
0011 #if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH)
0012 #pragma GCC diagnostic pop
0013 #endif
0014 
0015 #include <ap_int.h>
0016 #include <cassert>
0017 #include <cmath>
0018 
0019 namespace l1ct {
0020 
0021   typedef ap_ufixed<14, 12, AP_TRN, AP_SAT> pt_t;
0022   typedef ap_ufixed<10, 8, AP_TRN, AP_SAT> pt10_t;
0023   typedef ap_fixed<16, 14, AP_TRN, AP_SAT> dpt_t;
0024   typedef ap_ufixed<28, 24, AP_TRN, AP_SAT> pt2_t;
0025   typedef ap_int<10> eta_t;
0026   typedef ap_int<10> phi_t;
0027   typedef ap_int<6> tkdeta_t;
0028   typedef ap_uint<7> tkdphi_t;
0029   typedef ap_int<12> glbeta_t;
0030   typedef ap_int<11> glbphi_t;
0031   typedef ap_int<5> vtx_t;
0032   typedef ap_int<10> z0_t;         // 40cm / 0.1
0033   typedef ap_int<8> dxy_t;         // tbd
0034   typedef ap_uint<3> tkquality_t;  // tbd
0035   typedef ap_uint<9> puppiWgt_t;   // 256 = 1.0
0036   typedef ap_uint<6> emid_t;
0037   typedef ap_uint<14> tk2em_dr_t;
0038   typedef ap_uint<14> tk2calo_dr_t;
0039   typedef ap_uint<10> em2calo_dr_t;
0040   typedef ap_uint<13> tk2calo_dq_t;
0041   typedef ap_uint<4> egquality_t;
0042   // FIXME: adjust range 10-11bits -> 1/4 - 1/2TeV is probably more than enough for all reasonable use cases
0043   typedef ap_ufixed<11, 9, AP_TRN, AP_SAT> iso_t;
0044 
0045   struct ParticleID {
0046     ap_uint<3> bits;
0047     enum PID {
0048       NONE = 0,
0049       HADZERO = 0,
0050       PHOTON = 1,
0051       HADMINUS = 2,
0052       HADPLUS = 3,
0053       ELEMINUS = 4,
0054       ELEPLUS = 5,
0055       MUMINUS = 6,
0056       MUPLUS = 7
0057     };
0058     enum PTYPE { HAD = 0, EM = 1, MU = 2 };
0059 
0060     ParticleID(PID val = NONE) : bits(val) {}
0061     ParticleID &operator=(PID val) {
0062       bits = val;
0063       return *this;
0064     }
0065 
0066     int rawId() const { return bits.to_int(); }
0067     bool isPhoton() const {
0068 #ifndef __SYNTHESIS__
0069       assert(neutral());
0070 #endif
0071       return bits[0];
0072     }
0073     bool isMuon() const { return bits[2] && bits[1]; }
0074     bool isElectron() const { return bits[2] && !bits[1]; }
0075     bool isChargedHadron() const { return !bits[2] && bits[1]; }
0076     bool charge() const {
0077 #ifndef __SYNTHESIS__
0078       assert(charged());
0079 #endif
0080       return bits[0]; /* 1 if positive, 0 if negative */
0081     }
0082 
0083     bool chargeOrNull() const {  // doesn't throw on null id
0084       return bits[0];
0085     }
0086     bool charged() const { return bits[1] || bits[2]; };
0087     bool neutral() const { return !charged(); }
0088     int intCharge() const { return charged() ? (charge() ? +1 : -1) : 0; }
0089 
0090     void clear() { bits = 0; }
0091 
0092     static ParticleID mkChHad(bool charge) { return ParticleID(charge ? HADPLUS : HADMINUS); }
0093     static ParticleID mkElectron(bool charge) { return ParticleID(charge ? ELEPLUS : ELEMINUS); }
0094     static ParticleID mkMuon(bool charge) { return ParticleID(charge ? MUPLUS : MUMINUS); }
0095 
0096     inline bool operator==(const ParticleID &other) const { return bits == other.bits; }
0097 
0098     inline int pdgId() const {
0099       switch (bits.to_int()) {
0100         case HADZERO:
0101           return 130;
0102         case PHOTON:
0103           return 22;
0104         case HADMINUS:
0105           return -211;
0106         case HADPLUS:
0107           return +211;
0108         case ELEMINUS:
0109           return +11;
0110         case ELEPLUS:
0111           return -11;
0112         case MUMINUS:
0113           return +13;
0114         case MUPLUS:
0115           return -13;
0116       }
0117       return 0;
0118     }
0119 
0120     inline int oldId() const {
0121       //{ PID_Charged=0, PID_Neutral=1, PID_Photon=2, PID_Electron=3, PID_Muon=4 };
0122       switch (bits.to_int()) {
0123         case HADZERO:
0124           return 1;
0125         case PHOTON:
0126           return 2;
0127         case HADMINUS:
0128           return 0;
0129         case HADPLUS:
0130           return 0;
0131         case ELEMINUS:
0132           return 3;
0133         case ELEPLUS:
0134           return 3;
0135         case MUMINUS:
0136           return 4;
0137         case MUPLUS:
0138           return 4;
0139       }
0140       return -1;
0141     }
0142   };
0143 
0144   namespace Scales {
0145     constexpr int INTPHI_PI = 720;
0146     constexpr int INTPHI_TWOPI = 2 * INTPHI_PI;
0147     constexpr float INTPT_LSB = 0.25;
0148     constexpr float ETAPHI_LSB = M_PI / INTPHI_PI;
0149     constexpr float Z0_LSB = 0.05;
0150     constexpr float DXY_LSB = 0.05;
0151     constexpr float PUPPIW_LSB = 1.0 / 256;
0152     inline float floatPt(pt_t pt) { return pt.to_float(); }
0153     inline float floatPt(dpt_t pt) { return pt.to_float(); }
0154     inline float floatPt(pt2_t pt2) { return pt2.to_float(); }
0155     inline int intPt(pt_t pt) { return (ap_ufixed<16, 14>(pt) << 2).to_int(); }
0156     inline int intPt(dpt_t pt) { return (ap_fixed<18, 16>(pt) << 2).to_int(); }
0157     inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0158     inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0159     inline float floatEta(tkdeta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0160     inline float floatPhi(tkdphi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0161     inline float floatEta(glbeta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0162     inline float floatPhi(glbphi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0163     inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_LSB; }
0164     inline float floatDxy(dxy_t dxy) { return dxy.to_float() * DXY_LSB; }
0165     inline float floatPuppiW(puppiWgt_t puppiw) { return puppiw.to_float() * PUPPIW_LSB; }
0166     inline float floatIso(iso_t iso) { return iso.to_float(); }
0167 
0168     inline pt_t makePt(int pt) { return ap_ufixed<16, 14>(pt) >> 2; }
0169     inline dpt_t makeDPt(int dpt) { return ap_fixed<18, 16>(dpt) >> 2; }
0170     inline pt_t makePtFromFloat(float pt) { return pt_t(0.25 * round(pt * 4)); }
0171     inline dpt_t makeDPtFromFloat(float dpt) { return dpt_t(dpt); }
0172     inline z0_t makeZ0(float z0) { return z0_t(round(z0 / Z0_LSB)); }
0173 
0174     inline ap_uint<pt_t::width> ptToInt(pt_t pt) {
0175       // note: this can be synthethized, e.g. when pT is used as intex in a LUT
0176       ap_uint<pt_t::width> ret = 0;
0177       ret(pt_t::width - 1, 0) = pt(pt_t::width - 1, 0);
0178       return ret;
0179     }
0180 
0181     inline ap_int<dpt_t::width> ptToInt(dpt_t pt) {
0182       // note: this can be synthethized, e.g. when pT is used as intex in a LUT
0183       ap_uint<dpt_t::width> ret = 0;
0184       ret(dpt_t::width - 1, 0) = pt(dpt_t::width - 1, 0);
0185       return ret;
0186     }
0187 
0188     inline phi_t makePhi(float phi) { return round(phi / ETAPHI_LSB); }
0189     inline eta_t makeEta(float eta) { return round(eta / ETAPHI_LSB); }
0190     inline glbeta_t makeGlbEta(float eta) { return round(eta / ETAPHI_LSB); }
0191     inline glbeta_t makeGlbEtaRoundEven(float eta) { return 2 * std::round(eta / ETAPHI_LSB / 2); }
0192 
0193     inline glbphi_t makeGlbPhi(float phi) { return round(phi / ETAPHI_LSB); }
0194     inline iso_t makeIso(float iso) { return iso_t(0.25 * round(iso * 4)); }
0195 
0196     inline int makeDR2FromFloatDR(float dr) { return ceil(dr * dr / ETAPHI_LSB / ETAPHI_LSB); }
0197 
0198     inline float maxAbsEta() { return ((1 << (eta_t::width - 1)) - 1) * ETAPHI_LSB; }
0199     inline float maxAbsPhi() { return ((1 << (phi_t::width - 1)) - 1) * ETAPHI_LSB; }
0200     inline float maxAbsGlbEta() { return ((1 << (glbeta_t::width - 1)) - 1) * ETAPHI_LSB; }
0201     inline float maxAbsGlbPhi() { return ((1 << (glbphi_t::width - 1)) - 1) * ETAPHI_LSB; }
0202   };  // namespace Scales
0203 
0204   inline int dr2_int(eta_t eta1, phi_t phi1, eta_t eta2, phi_t phi2) {
0205     ap_int<eta_t::width + 1> deta = (eta1 - eta2);
0206     ap_int<phi_t::width + 1> dphi = (phi1 - phi2);
0207     return deta * deta + dphi * dphi;
0208   }
0209 
0210 }  // namespace l1ct
0211 
0212 #endif