Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-06-23 01:38:31

0001 #ifndef DataFormats_L1TParticleFlow_gt_datatypes_h
0002 #define DataFormats_L1TParticleFlow_gt_datatypes_h
0003 
0004 #if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH)
0005 #pragma GCC diagnostic push
0006 #pragma GCC diagnostic ignored "-Wuninitialized"
0007 #endif
0008 #include <ap_int.h>
0009 #if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH)
0010 #pragma GCC diagnostic pop
0011 #endif
0012 
0013 #include "DataFormats/L1TParticleFlow/interface/bit_encoding.h"
0014 #include <array>
0015 #include <cstdint>
0016 
0017 namespace l1gt {
0018   // Using rounding & saturation modes to avoid unnecessary rounding errors
0019   // Don't saturate phi since -π to +π periodicity is handled by numerical wrap around
0020   // Rounding and saturation settings are lost when sending the data over the link
0021   // Unless the receiving end uses the same data types
0022 
0023   // Common fields
0024   typedef ap_ufixed<16, 11, AP_RND_CONV, AP_SAT> pt_t;
0025   typedef ap_fixed<13, 13, AP_RND_CONV> phi_t;
0026   typedef ap_fixed<14, 14, AP_RND_CONV, AP_SAT> eta_t;
0027   typedef ap_fixed<10, 9, AP_RND_CONV, AP_SAT> z0_t;
0028   typedef ap_uint<1> valid_t;
0029 
0030   // E/gamma fields
0031   typedef ap_ufixed<11, 9> iso_t;
0032   typedef ap_uint<4> egquality_t;
0033 
0034   // tau fields
0035   typedef ap_ufixed<10, 8> tauseed_pt_t;
0036   typedef ap_uint<10> tau_rawid_t;
0037   typedef std::array<uint64_t, 2> PackedTau;
0038 
0039   namespace Scales {
0040     const int INTPHI_PI = 1 << (phi_t::width - 1);
0041     const float INTPT_LSB = 1.0 / (1 << (pt_t::width - pt_t::iwidth));
0042     const int INTPHI_TWOPI = 2 * INTPHI_PI;
0043     constexpr float ETAPHI_LSB = M_PI / INTPHI_PI;
0044     inline float floatPt(pt_t pt) { return pt.to_float(); }
0045     inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0046     inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0047   }  // namespace Scales
0048 
0049   struct ThreeVector {
0050     pt_t pt;
0051     phi_t phi;
0052     eta_t eta;
0053 
0054     inline bool operator==(const ThreeVector &other) const {
0055       return pt == other.pt && phi == other.phi && eta == other.eta;
0056     }
0057 
0058     static const int BITWIDTH = pt_t::width + phi_t::width + eta_t::width;
0059     inline ap_uint<BITWIDTH> pack() const {
0060       ap_uint<BITWIDTH> ret;
0061       unsigned int start = 0;
0062       pack_into_bits(ret, start, pt);
0063       pack_into_bits(ret, start, phi);
0064       pack_into_bits(ret, start, eta);
0065       return ret;
0066     }
0067 
0068     inline static ThreeVector unpack_ap(const ap_uint<BITWIDTH> &src) {
0069       ThreeVector ret;
0070       ret.initFromBits(src);
0071       return ret;
0072     }
0073 
0074     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0075       unsigned int start = 0;
0076       unpack_from_bits(src, start, pt);
0077       unpack_from_bits(src, start, phi);
0078       unpack_from_bits(src, start, eta);
0079     }
0080   };
0081 
0082   struct Jet {
0083     valid_t valid;
0084     ThreeVector v3;
0085     z0_t z0;
0086 
0087     inline bool operator==(const Jet &other) const { return valid == other.valid && z0 == other.z0 && v3 == other.v3; }
0088 
0089     static const int BITWIDTH = 128;
0090     inline ap_uint<BITWIDTH> pack_ap() const {
0091       ap_uint<BITWIDTH> ret = 0;
0092       unsigned int start = 0;
0093       pack_into_bits(ret, start, valid);
0094       pack_into_bits(ret, start, v3.pack());
0095       pack_into_bits(ret, start, z0);
0096       return ret;
0097     }
0098 
0099     inline std::array<uint64_t, 2> pack() const {
0100       std::array<uint64_t, 2> packed;
0101       ap_uint<BITWIDTH> bits = this->pack_ap();
0102       packed[0] = bits(63, 0);
0103       packed[1] = bits(127, 64);
0104       return packed;
0105     }
0106 
0107     inline static Jet unpack_ap(const ap_uint<BITWIDTH> &src) {
0108       Jet ret;
0109       ret.initFromBits(src);
0110       return ret;
0111     }
0112 
0113     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0114       unsigned int start = 0;
0115       unpack_from_bits(src, start, valid);
0116       unpack_from_bits(src, start, v3.pt);
0117       unpack_from_bits(src, start, v3.phi);
0118       unpack_from_bits(src, start, v3.eta);
0119       unpack_from_bits(src, start, z0);
0120     }
0121 
0122     inline static Jet unpack(const std::array<uint64_t, 2> &src) {
0123       ap_uint<BITWIDTH> bits;
0124       bits(63, 0) = src[0];
0125       bits(127, 64) = src[1];
0126       return unpack_ap(bits);
0127     }
0128 
0129     inline static Jet unpack(long long unsigned int &src) {
0130       // unpack from single 64b int
0131       ap_uint<BITWIDTH> bits = src;
0132       return unpack_ap(bits);
0133     }
0134 
0135   };  // struct Jet
0136 
0137   struct Sum {
0138     valid_t valid;
0139     pt_t vector_pt;
0140     phi_t vector_phi;
0141     pt_t scalar_pt;
0142 
0143     inline bool operator==(const Sum &other) const {
0144       return valid == other.valid && vector_pt == other.vector_pt && vector_phi == other.vector_phi &&
0145              scalar_pt == other.scalar_pt;
0146     }
0147 
0148     inline void clear() {
0149       valid = 0;
0150       vector_pt = 0;
0151       vector_phi = 0;
0152       scalar_pt = 0;
0153     }
0154 
0155     static const int BITWIDTH = 64;
0156     inline ap_uint<BITWIDTH> pack() const {
0157       ap_uint<BITWIDTH> ret;
0158       unsigned int start = 0;
0159       pack_into_bits(ret, start, valid);
0160       pack_into_bits(ret, start, vector_pt);
0161       pack_into_bits(ret, start, vector_phi);
0162       pack_into_bits(ret, start, scalar_pt);
0163       return ret;
0164     }
0165 
0166     inline static Sum unpack_ap(const ap_uint<BITWIDTH> &src) {
0167       Sum ret;
0168       ret.initFromBits(src);
0169       return ret;
0170     }
0171 
0172     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0173       unsigned int start = 0;
0174       unpack_from_bits(src, start, valid);
0175       unpack_from_bits(src, start, vector_pt);
0176       unpack_from_bits(src, start, vector_phi);
0177       unpack_from_bits(src, start, scalar_pt);
0178     }
0179   };  // struct Sum
0180 
0181   struct Tau {
0182     valid_t valid;
0183     ThreeVector v3;
0184     tauseed_pt_t seed_pt;
0185     z0_t seed_z0;
0186     ap_uint<1> charge;
0187     ap_uint<2> type;
0188     tau_rawid_t isolation;
0189     ap_uint<2> id0;
0190     ap_uint<2> id1;
0191 
0192     static const int BITWIDTH = 128;
0193     inline ap_uint<BITWIDTH> pack_ap() const {
0194       ap_uint<BITWIDTH> ret;
0195       unsigned int start = 0;
0196       pack_into_bits(ret, start, valid);
0197       pack_into_bits(ret, start, v3.pack());
0198       pack_into_bits(ret, start, seed_pt);
0199       pack_into_bits(ret, start, seed_z0);
0200       pack_into_bits(ret, start, charge);
0201       pack_into_bits(ret, start, type);
0202       pack_into_bits(ret, start, isolation);
0203       pack_into_bits(ret, start, id0);
0204       pack_into_bits(ret, start, id1);
0205       return ret;
0206     }
0207 
0208     inline PackedTau pack() const {
0209       PackedTau packed;
0210       ap_uint<BITWIDTH> bits = this->pack_ap();
0211       packed[0] = bits(63, 0);
0212       packed[1] = bits(127, 64);
0213       return packed;
0214     }
0215 
0216     inline static Tau unpack_ap(const ap_uint<BITWIDTH> &src) {
0217       Tau ret;
0218       ret.initFromBits(src);
0219       return ret;
0220     }
0221 
0222     inline static Tau unpack(const PackedTau &src) {
0223       ap_uint<BITWIDTH> bits;
0224       bits(63, 0) = src[0];
0225       bits(127, 64) = src[1];
0226 
0227       return unpack_ap(bits);
0228     }
0229 
0230     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0231       unsigned int start = 0;
0232       unpack_from_bits(src, start, valid);
0233       unpack_from_bits(src, start, v3.pt);
0234       unpack_from_bits(src, start, v3.phi);
0235       unpack_from_bits(src, start, v3.eta);
0236       unpack_from_bits(src, start, seed_pt);
0237       unpack_from_bits(src, start, seed_z0);
0238       unpack_from_bits(src, start, charge);
0239       unpack_from_bits(src, start, type);
0240       unpack_from_bits(src, start, isolation);
0241       unpack_from_bits(src, start, id0);
0242       unpack_from_bits(src, start, id1);
0243     }
0244 
0245   };  // struct Tau
0246 
0247   struct Electron {
0248     valid_t valid;
0249     ThreeVector v3;
0250     egquality_t quality;
0251     ap_uint<1> charge;
0252     z0_t z0;
0253     iso_t isolation;
0254 
0255     static const int BITWIDTH = 96;
0256     inline ap_uint<BITWIDTH> pack() const {
0257       ap_uint<BITWIDTH> ret(0);
0258       unsigned int start = 0;
0259       pack_into_bits(ret, start, valid);
0260       pack_into_bits(ret, start, v3.pack());
0261       pack_into_bits(ret, start, quality);
0262       pack_into_bits(ret, start, isolation);
0263       pack_into_bits(ret, start, charge);
0264       pack_into_bits(ret, start, z0);
0265       return ret;
0266     }
0267 
0268     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0269       unsigned int start = 0;
0270       unpack_from_bits(src, start, valid);
0271       unpack_from_bits(src, start, v3.pt);
0272       unpack_from_bits(src, start, v3.phi);
0273       unpack_from_bits(src, start, v3.eta);
0274       unpack_from_bits(src, start, quality);
0275       unpack_from_bits(src, start, isolation);
0276       unpack_from_bits(src, start, charge);
0277       unpack_from_bits(src, start, z0);
0278     }
0279 
0280     inline static Electron unpack_ap(const ap_uint<BITWIDTH> &src) {
0281       Electron ret;
0282       ret.initFromBits(src);
0283       return ret;
0284     }
0285 
0286     inline static Electron unpack(const std::array<uint64_t, 2> &src, int parity) {
0287       ap_uint<BITWIDTH> bits;
0288       if (parity == 0) {
0289         bits(63, 0) = src[0];
0290         bits(95, 64) = src[1];
0291       } else {
0292         bits(63, 0) = src[1];
0293         bits(95, 64) = (src[0] >> 32);
0294       }
0295       return unpack_ap(bits);
0296     }
0297   };
0298 
0299   struct Photon {
0300     valid_t valid;
0301     ThreeVector v3;
0302     egquality_t quality;
0303     iso_t isolation;
0304 
0305     static const int BITWIDTH = 96;
0306     inline ap_uint<BITWIDTH> pack() const {
0307       ap_uint<96> ret(0);
0308       unsigned int start = 0;
0309       pack_into_bits(ret, start, valid);
0310       pack_into_bits(ret, start, v3.pack());
0311       pack_into_bits(ret, start, quality);
0312       pack_into_bits(ret, start, isolation);
0313       return ret;
0314     }
0315 
0316     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0317       unsigned int start = 0;
0318       unpack_from_bits(src, start, valid);
0319       unpack_from_bits(src, start, v3.pt);
0320       unpack_from_bits(src, start, v3.phi);
0321       unpack_from_bits(src, start, v3.eta);
0322       unpack_from_bits(src, start, quality);
0323       unpack_from_bits(src, start, isolation);
0324     }
0325 
0326     inline static Photon unpack_ap(const ap_uint<BITWIDTH> &src) {
0327       Photon ret;
0328       ret.initFromBits(src);
0329       return ret;
0330     }
0331 
0332     inline static Photon unpack(const std::array<uint64_t, 2> &src, int parity) {
0333       ap_uint<BITWIDTH> bits;
0334       if (parity == 0) {
0335         bits(63, 0) = src[0];
0336         bits(95, 64) = src[1];
0337       } else {
0338         bits(63, 0) = src[1];
0339         bits(95, 64) = (src[0] >> 32);
0340       }
0341       return unpack_ap(bits);
0342     }
0343   };
0344 
0345 }  // namespace l1gt
0346 
0347 namespace l1ct {
0348 
0349   typedef ap_fixed<18, 5, AP_RND_CONV, AP_SAT> etaphi_sf_t;  // use a DSP input width
0350 
0351   namespace Scales {
0352     const etaphi_sf_t ETAPHI_CTtoGT_SCALE = (Scales::ETAPHI_LSB / l1gt::Scales::ETAPHI_LSB);
0353   }
0354 
0355   inline l1gt::pt_t CTtoGT_pt(pt_t x) {
0356     // the CT & GT pT are both ap_fixed with different power-of-2 LSBs
0357     // -> conversion is just a cast
0358     return (l1gt::pt_t)x;
0359   }
0360 
0361   inline l1gt::eta_t CTtoGT_eta(glbeta_t x) {
0362     // rescale the eta into the GT coordinates
0363     return x * Scales::ETAPHI_CTtoGT_SCALE;
0364   }
0365 
0366   inline l1gt::phi_t CTtoGT_phi(glbphi_t x) {
0367     // rescale the phi into the GT coordinates
0368     return x * Scales::ETAPHI_CTtoGT_SCALE;
0369   }
0370 
0371 }  // namespace l1ct
0372 
0373 #endif