Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-11 03:34:01

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