Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-02-08 02:59:58

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