Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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   // While bitwise identical to the l1ct::z0_t value, we store z0 in mm to profit of ap_fixed goodies
0028   typedef ap_fixed<10, 9, AP_RND_CONV, AP_SAT> z0_t;  // NOTE: mm instead of cm!!!
0029   typedef ap_ufixed<10, 1, AP_RND, AP_SAT> b_tag_score_t;
0030   typedef ap_uint<1> valid_t;
0031 
0032   // E/gamma fields
0033   typedef ap_ufixed<11, 9> iso_t;
0034   typedef ap_uint<4> egquality_t;
0035 
0036   // tau fields
0037   typedef ap_ufixed<10, 8> tauseed_pt_t;
0038   typedef ap_uint<10> tau_quality_t;
0039   typedef std::array<uint64_t, 2> PackedTau;
0040 
0041   namespace Scales {
0042     const int INTPHI_PI = 1 << (phi_t::width - 1);
0043     const float INTPT_LSB = 1.0 / (1 << (pt_t::width - pt_t::iwidth));
0044     const int INTPHI_TWOPI = 2 * INTPHI_PI;
0045     constexpr float ETAPHI_LSB = M_PI / INTPHI_PI;
0046     constexpr float Z0_UNITS = 0.1;  // 1 L1 unit is 1 mm, while CMS standard units are cm
0047     inline float floatPt(pt_t pt) { return pt.to_float(); }
0048     inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0049     inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0050     inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_UNITS; }
0051   }  // namespace Scales
0052 
0053   struct ThreeVector {
0054     pt_t pt;
0055     phi_t phi;
0056     eta_t eta;
0057 
0058     inline bool operator==(const ThreeVector &other) const {
0059       return pt == other.pt && phi == other.phi && eta == other.eta;
0060     }
0061 
0062     static const int BITWIDTH = pt_t::width + phi_t::width + eta_t::width;
0063     inline ap_uint<BITWIDTH> pack() const {
0064       ap_uint<BITWIDTH> ret;
0065       unsigned int start = 0;
0066       pack_into_bits(ret, start, pt);
0067       pack_into_bits(ret, start, phi);
0068       pack_into_bits(ret, start, eta);
0069       return ret;
0070     }
0071 
0072     inline static ThreeVector unpack_ap(const ap_uint<BITWIDTH> &src) {
0073       ThreeVector ret;
0074       ret.initFromBits(src);
0075       return ret;
0076     }
0077 
0078     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0079       unsigned int start = 0;
0080       unpack_from_bits(src, start, pt);
0081       unpack_from_bits(src, start, phi);
0082       unpack_from_bits(src, start, eta);
0083     }
0084   };
0085 
0086   struct Jet {
0087     valid_t valid;
0088     ThreeVector v3;
0089     z0_t z0;
0090     b_tag_score_t hwBtagScore;
0091 
0092     inline bool operator==(const Jet &other) const { return valid == other.valid && z0 == other.z0 && v3 == other.v3; }
0093 
0094     static const int BITWIDTH = 128;
0095     inline ap_uint<BITWIDTH> pack_ap() const {
0096       ap_uint<BITWIDTH> ret = 0;
0097       unsigned int start = 0;
0098       pack_into_bits(ret, start, valid);
0099       pack_into_bits(ret, start, v3.pack());
0100       pack_into_bits(ret, start, z0);
0101       pack_into_bits(ret, start, hwBtagScore);
0102       return ret;
0103     }
0104 
0105     inline std::array<uint64_t, 2> pack() const {
0106       std::array<uint64_t, 2> packed;
0107       ap_uint<BITWIDTH> bits = this->pack_ap();
0108       packed[0] = bits(63, 0);
0109       packed[1] = bits(127, 64);
0110       return packed;
0111     }
0112 
0113     inline static Jet unpack_ap(const ap_uint<BITWIDTH> &src) {
0114       Jet ret;
0115       ret.initFromBits(src);
0116       return ret;
0117     }
0118 
0119     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0120       unsigned int start = 0;
0121       unpack_from_bits(src, start, valid);
0122       unpack_from_bits(src, start, v3.pt);
0123       unpack_from_bits(src, start, v3.phi);
0124       unpack_from_bits(src, start, v3.eta);
0125       unpack_from_bits(src, start, z0);
0126       unpack_from_bits(src, start, hwBtagScore);
0127     }
0128 
0129     inline static Jet unpack(const std::array<uint64_t, 2> &src) {
0130       ap_uint<BITWIDTH> bits;
0131       bits(63, 0) = src[0];
0132       bits(127, 64) = src[1];
0133       return unpack_ap(bits);
0134     }
0135 
0136     inline static Jet unpack(long long unsigned int &src) {
0137       // unpack from single 64b int
0138       ap_uint<BITWIDTH> bits = src;
0139       return unpack_ap(bits);
0140     }
0141 
0142   };  // struct Jet
0143 
0144   struct Sum {
0145     valid_t valid;
0146     pt_t vector_pt;
0147     phi_t vector_phi;
0148     pt_t scalar_pt;
0149 
0150     inline bool operator==(const Sum &other) const {
0151       return valid == other.valid && vector_pt == other.vector_pt && vector_phi == other.vector_phi &&
0152              scalar_pt == other.scalar_pt;
0153     }
0154 
0155     inline void clear() {
0156       valid = 0;
0157       vector_pt = 0;
0158       vector_phi = 0;
0159       scalar_pt = 0;
0160     }
0161 
0162     static const int BITWIDTH = 64;
0163     inline ap_uint<BITWIDTH> pack_ap() const {
0164       ap_uint<BITWIDTH> ret(0);
0165       unsigned int start = 0;
0166       pack_into_bits(ret, start, valid);
0167       pack_into_bits(ret, start, vector_pt);
0168       pack_into_bits(ret, start, vector_phi);
0169       pack_into_bits(ret, start, scalar_pt);
0170       return ret;
0171     }
0172 
0173     inline uint64_t pack() const {
0174       ap_uint<BITWIDTH> x = pack_ap();
0175       return (uint64_t)x;
0176     }
0177 
0178     inline static Sum unpack_ap(const ap_uint<BITWIDTH> &src) {
0179       Sum ret;
0180       ret.initFromBits(src);
0181       return ret;
0182     }
0183 
0184     inline static Sum unpack(const uint64_t &src) { return unpack_ap(src); }
0185 
0186     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0187       unsigned int start = 0;
0188       unpack_from_bits(src, start, valid);
0189       unpack_from_bits(src, start, vector_pt);
0190       unpack_from_bits(src, start, vector_phi);
0191       unpack_from_bits(src, start, scalar_pt);
0192     }
0193   };  // struct Sum
0194 
0195   struct Tau {
0196     valid_t valid;
0197     ThreeVector v3;
0198     tauseed_pt_t seed_pt;
0199     z0_t seed_z0;
0200     ap_uint<1> charge;
0201     ap_uint<2> type;
0202     tau_quality_t quality;
0203     ap_uint<2> id0;
0204     ap_uint<2> id1;
0205 
0206     static const int BITWIDTH = 128;
0207     inline ap_uint<BITWIDTH> pack_ap() const {
0208       ap_uint<BITWIDTH> ret(0);
0209       unsigned int start = 0;
0210       pack_into_bits(ret, start, valid);
0211       pack_into_bits(ret, start, v3.pack());
0212       pack_into_bits(ret, start, seed_pt);
0213       pack_into_bits(ret, start, seed_z0);
0214       pack_into_bits(ret, start, charge);
0215       pack_into_bits(ret, start, type);
0216       pack_into_bits(ret, start, quality);
0217       pack_into_bits(ret, start, id0);
0218       pack_into_bits(ret, start, id1);
0219       return ret;
0220     }
0221 
0222     inline PackedTau pack() const {
0223       PackedTau packed;
0224       ap_uint<BITWIDTH> bits = this->pack_ap();
0225       packed[0] = bits(63, 0);
0226       packed[1] = bits(127, 64);
0227       return packed;
0228     }
0229 
0230     inline static Tau unpack_ap(const ap_uint<BITWIDTH> &src) {
0231       Tau ret;
0232       ret.initFromBits(src);
0233       return ret;
0234     }
0235 
0236     inline static Tau unpack(const PackedTau &src) {
0237       ap_uint<BITWIDTH> bits;
0238       bits(63, 0) = src[0];
0239       bits(127, 64) = src[1];
0240 
0241       return unpack_ap(bits);
0242     }
0243 
0244     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0245       unsigned int start = 0;
0246       unpack_from_bits(src, start, valid);
0247       unpack_from_bits(src, start, v3.pt);
0248       unpack_from_bits(src, start, v3.phi);
0249       unpack_from_bits(src, start, v3.eta);
0250       unpack_from_bits(src, start, seed_pt);
0251       unpack_from_bits(src, start, seed_z0);
0252       unpack_from_bits(src, start, charge);
0253       unpack_from_bits(src, start, type);
0254       unpack_from_bits(src, start, quality);
0255       unpack_from_bits(src, start, id0);
0256       unpack_from_bits(src, start, id1);
0257     }
0258 
0259   };  // struct Tau
0260 
0261   struct Electron {
0262     valid_t valid;
0263     ThreeVector v3;
0264     egquality_t qualityFlags;
0265     ap_uint<1> charge;
0266     z0_t z0;
0267     iso_t isolationPT;
0268 
0269     static const int BITWIDTH = 96;
0270     inline ap_uint<BITWIDTH> pack() const {
0271       ap_uint<BITWIDTH> ret(0);
0272       unsigned int start = 0;
0273       pack_into_bits(ret, start, valid);
0274       pack_into_bits(ret, start, v3.pack());
0275       pack_into_bits(ret, start, qualityFlags);
0276       pack_into_bits(ret, start, isolationPT);
0277       pack_into_bits(ret, start, charge);
0278       pack_into_bits(ret, start, z0);
0279       return ret;
0280     }
0281 
0282     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0283       unsigned int start = 0;
0284       unpack_from_bits(src, start, valid);
0285       unpack_from_bits(src, start, v3.pt);
0286       unpack_from_bits(src, start, v3.phi);
0287       unpack_from_bits(src, start, v3.eta);
0288       unpack_from_bits(src, start, qualityFlags);
0289       unpack_from_bits(src, start, isolationPT);
0290       unpack_from_bits(src, start, charge);
0291       unpack_from_bits(src, start, z0);
0292     }
0293 
0294     inline static Electron unpack_ap(const ap_uint<BITWIDTH> &src) {
0295       Electron ret;
0296       ret.initFromBits(src);
0297       return ret;
0298     }
0299 
0300     inline static Electron unpack(const std::array<uint64_t, 2> &src, int parity) {
0301       ap_uint<BITWIDTH> bits;
0302       if (parity == 0) {
0303         bits(63, 0) = src[0];
0304         bits(95, 64) = src[1];
0305       } else {
0306         bits(63, 0) = src[1];
0307         bits(95, 64) = (src[0] >> 32);
0308       }
0309       return unpack_ap(bits);
0310     }
0311   };
0312 
0313   struct Photon {
0314     valid_t valid;
0315     ThreeVector v3;
0316     egquality_t qualityFlags;
0317     iso_t isolationPT;
0318 
0319     static const int BITWIDTH = 96;
0320     inline ap_uint<BITWIDTH> pack() const {
0321       ap_uint<96> ret(0);
0322       unsigned int start = 0;
0323       pack_into_bits(ret, start, valid);
0324       pack_into_bits(ret, start, v3.pack());
0325       pack_into_bits(ret, start, qualityFlags);
0326       pack_into_bits(ret, start, isolationPT);
0327       return ret;
0328     }
0329 
0330     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0331       unsigned int start = 0;
0332       unpack_from_bits(src, start, valid);
0333       unpack_from_bits(src, start, v3.pt);
0334       unpack_from_bits(src, start, v3.phi);
0335       unpack_from_bits(src, start, v3.eta);
0336       unpack_from_bits(src, start, qualityFlags);
0337       unpack_from_bits(src, start, isolationPT);
0338     }
0339 
0340     inline static Photon unpack_ap(const ap_uint<BITWIDTH> &src) {
0341       Photon ret;
0342       ret.initFromBits(src);
0343       return ret;
0344     }
0345 
0346     inline static Photon unpack(const std::array<uint64_t, 2> &src, int parity) {
0347       ap_uint<BITWIDTH> bits(0);
0348       if (parity == 0) {
0349         bits(63, 0) = src[0];
0350         bits(95, 64) = src[1];
0351       } else {
0352         bits(63, 0) = src[1];
0353         bits(95, 64) = (src[0] >> 32);
0354       }
0355       return unpack_ap(bits);
0356     }
0357   };
0358 
0359 }  // namespace l1gt
0360 
0361 namespace l1ct {
0362 
0363   typedef ap_fixed<18, 5, AP_RND_CONV, AP_SAT> etaphi_sf_t;  // use a DSP input width
0364 
0365   namespace Scales {
0366     const etaphi_sf_t ETAPHI_CTtoGT_SCALE = (Scales::ETAPHI_LSB / l1gt::Scales::ETAPHI_LSB);
0367   }
0368 
0369   inline l1gt::pt_t CTtoGT_pt(pt_t x) {
0370     // the CT & GT pT are both ap_fixed with different power-of-2 LSBs
0371     // -> conversion is just a cast
0372     return (l1gt::pt_t)x;
0373   }
0374 
0375   inline l1gt::eta_t CTtoGT_eta(glbeta_t x) {
0376     // rescale the eta into the GT coordinates
0377     return x * Scales::ETAPHI_CTtoGT_SCALE;
0378   }
0379 
0380   inline l1gt::phi_t CTtoGT_phi(glbphi_t x) {
0381     // rescale the phi into the GT coordinates
0382     return x * Scales::ETAPHI_CTtoGT_SCALE;
0383   }
0384 
0385 }  // namespace l1ct
0386 
0387 #endif