Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-20 01:53:07

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