Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-05-09 22:37:29

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<8, 1, AP_RND, AP_SAT> id_proba_t;  // for IDs bounded in range [0-1]
0030   typedef ap_ufixed<10, 1, AP_RND, AP_SAT> n_prong_score_t;
0031   typedef ap_ufixed<17, 15, AP_RND_CONV, AP_SAT> mass2_t;
0032   typedef ap_uint<1> valid_t;
0033 
0034   // E/gamma fields
0035   typedef ap_ufixed<11, 9> iso_t;
0036   typedef ap_uint<4> egquality_t;
0037 
0038   // tau fields
0039   typedef ap_ufixed<10, 8> tauseed_pt_t;
0040   typedef ap_uint<10> tau_quality_t;
0041   typedef std::array<uint64_t, 2> PackedTau;
0042 
0043   namespace Scales {
0044     const int INTPHI_PI = 1 << (phi_t::width - 1);
0045     const float INTPT_LSB = 1.0 / (1 << (pt_t::width - pt_t::iwidth));
0046     const int INTPHI_TWOPI = 2 * INTPHI_PI;
0047     constexpr float ETAPHI_LSB = M_PI / INTPHI_PI;
0048     constexpr float Z0_UNITS = 0.1;  // 1 L1 unit is 1 mm, while CMS standard units are cm
0049     inline float floatPt(pt_t pt) { return pt.to_float(); }
0050     inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; }
0051     inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; }
0052     inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_UNITS; }
0053     inline float floatMassSq(mass2_t massSq) { return massSq.to_float(); }
0054   }  // namespace Scales
0055 
0056   struct ThreeVector {
0057     pt_t pt;
0058     phi_t phi;
0059     eta_t eta;
0060 
0061     inline bool operator==(const ThreeVector &other) const {
0062       return pt == other.pt && phi == other.phi && eta == other.eta;
0063     }
0064 
0065     static const int BITWIDTH = pt_t::width + phi_t::width + eta_t::width;
0066     inline ap_uint<BITWIDTH> pack() const {
0067       ap_uint<BITWIDTH> ret;
0068       unsigned int start = 0;
0069       pack_into_bits(ret, start, pt);
0070       pack_into_bits(ret, start, phi);
0071       pack_into_bits(ret, start, eta);
0072       return ret;
0073     }
0074 
0075     inline static ThreeVector unpack_ap(const ap_uint<BITWIDTH> &src) {
0076       ThreeVector ret;
0077       ret.initFromBits(src);
0078       return ret;
0079     }
0080 
0081     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0082       unsigned int start = 0;
0083       unpack_from_bits(src, start, pt);
0084       unpack_from_bits(src, start, phi);
0085       unpack_from_bits(src, start, eta);
0086     }
0087   };
0088 
0089   struct Jet {
0090     static const unsigned NTagFields = 8;
0091     valid_t valid;
0092     ThreeVector v3;
0093     z0_t z0;
0094     // class probabilities for tag categories
0095     id_proba_t hwTagScores[NTagFields];
0096 
0097     inline bool operator==(const Jet &other) const {
0098       bool eq = valid == other.valid && z0 == other.z0 && v3 == other.v3;
0099       for (unsigned i = 0; i < NTagFields; i++) {
0100         eq = eq && hwTagScores[i] == other.hwTagScores[i];
0101       }
0102       return eq;
0103     }
0104 
0105     static const int BITWIDTH = 128;
0106     inline ap_uint<BITWIDTH> pack_ap() const {
0107       ap_uint<BITWIDTH> ret = 0;
0108       unsigned int start = 0;
0109       pack_into_bits(ret, start, valid);
0110       pack_into_bits(ret, start, v3.pack());
0111       pack_into_bits(ret, start, z0);
0112       for (unsigned i = 0; i < NTagFields; i++) {
0113         pack_into_bits(ret, start, hwTagScores[i]);
0114       }
0115       return ret;
0116     }
0117 
0118     inline std::array<uint64_t, 2> pack() const {
0119       std::array<uint64_t, 2> packed;
0120       ap_uint<BITWIDTH> bits = this->pack_ap();
0121       packed[0] = bits(63, 0);
0122       packed[1] = bits(127, 64);
0123       return packed;
0124     }
0125 
0126     inline static Jet unpack_ap(const ap_uint<BITWIDTH> &src) {
0127       Jet ret;
0128       ret.initFromBits(src);
0129       return ret;
0130     }
0131 
0132     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0133       unsigned int start = 0;
0134       unpack_from_bits(src, start, valid);
0135       unpack_from_bits(src, start, v3.pt);
0136       unpack_from_bits(src, start, v3.phi);
0137       unpack_from_bits(src, start, v3.eta);
0138       unpack_from_bits(src, start, z0);
0139       for (unsigned i = 0; i < NTagFields; i++) {
0140         unpack_from_bits(src, start, hwTagScores[i]);
0141       }
0142     }
0143 
0144     inline static Jet unpack(const std::array<uint64_t, 2> &src) {
0145       ap_uint<BITWIDTH> bits;
0146       bits(63, 0) = src[0];
0147       bits(127, 64) = src[1];
0148       return unpack_ap(bits);
0149     }
0150 
0151     inline static Jet unpack(long long unsigned int &src) {
0152       // unpack from single 64b int
0153       ap_uint<BITWIDTH> bits = src;
0154       return unpack_ap(bits);
0155     }
0156 
0157     inline static Jet unpack(const std::array<long long unsigned int, 2> &src) {
0158       // unpack from two 64b ints
0159       ap_uint<BITWIDTH> bits;
0160       bits(63, 0) = src[0];
0161       bits(127, 64) = src[1];
0162       return unpack_ap(bits);
0163     }
0164 
0165   };  // struct Jet
0166 
0167   struct WideJet {
0168     valid_t valid;
0169     ThreeVector v3;
0170     z0_t z0;
0171     n_prong_score_t hwNProngScore;
0172     mass2_t hwMassSq;
0173 
0174     inline bool operator==(const WideJet &other) const {
0175       return valid == other.valid && z0 == other.z0 && hwNProngScore == other.hwNProngScore &&
0176              hwMassSq == other.hwMassSq && v3 == other.v3;
0177     }
0178 
0179     static const int BITWIDTH = 128;
0180     inline ap_uint<BITWIDTH> pack_ap() const {
0181       ap_uint<BITWIDTH> ret = 0;
0182       unsigned int start = 0;
0183       pack_into_bits(ret, start, valid);
0184       pack_into_bits(ret, start, v3.pack());
0185       pack_into_bits(ret, start, z0);
0186       pack_into_bits(ret, start, hwNProngScore);
0187       start = 64;  // Start second word
0188       pack_into_bits(ret, start, hwMassSq);
0189       return ret;
0190     }
0191 
0192     inline std::array<uint64_t, 2> pack() const {
0193       std::array<uint64_t, 2> packed;
0194       ap_uint<BITWIDTH> bits = this->pack_ap();
0195       packed[0] = bits(63, 0);
0196       packed[1] = bits(127, 64);
0197       return packed;
0198     }
0199 
0200     inline static WideJet unpack_ap(const ap_uint<BITWIDTH> &src) {
0201       WideJet ret;
0202       ret.initFromBits(src);
0203       return ret;
0204     }
0205 
0206     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0207       unsigned int start = 0;
0208       unpack_from_bits(src, start, valid);
0209       unpack_from_bits(src, start, v3.pt);
0210       unpack_from_bits(src, start, v3.phi);
0211       unpack_from_bits(src, start, v3.eta);
0212       unpack_from_bits(src, start, z0);
0213       unpack_from_bits(src, start, hwNProngScore);
0214       start = 64;  // Start second word
0215       unpack_from_bits(src, start, hwMassSq);
0216     }
0217 
0218     inline static WideJet unpack(const std::array<uint64_t, 2> &src) {
0219       ap_uint<BITWIDTH> bits;
0220       bits(63, 0) = src[0];
0221       bits(127, 64) = src[1];
0222       return unpack_ap(bits);
0223     }
0224 
0225     inline static WideJet unpack(long long unsigned int &src) {
0226       // unpack from single 64b int
0227       ap_uint<BITWIDTH> bits = src;
0228       return unpack_ap(bits);
0229     }
0230 
0231     inline static WideJet unpack(const std::array<long long unsigned int, 2> &src) {
0232       // unpack from two 64b ints
0233       ap_uint<BITWIDTH> bits;
0234       bits(63, 0) = src[0];
0235       bits(127, 64) = src[1];
0236       return unpack_ap(bits);
0237     }
0238 
0239   };  // struct WideJet
0240 
0241   struct Sum {
0242     valid_t valid;
0243     pt_t vector_pt;
0244     phi_t vector_phi;
0245     pt_t scalar_pt;
0246 
0247     inline bool operator==(const Sum &other) const {
0248       return valid == other.valid && vector_pt == other.vector_pt && vector_phi == other.vector_phi &&
0249              scalar_pt == other.scalar_pt;
0250     }
0251 
0252     inline void clear() {
0253       valid = 0;
0254       vector_pt = 0;
0255       vector_phi = 0;
0256       scalar_pt = 0;
0257     }
0258 
0259     static const int BITWIDTH = 64;
0260     inline ap_uint<BITWIDTH> pack_ap() const {
0261       ap_uint<BITWIDTH> ret(0);
0262       unsigned int start = 0;
0263       pack_into_bits(ret, start, valid);
0264       pack_into_bits(ret, start, vector_pt);
0265       pack_into_bits(ret, start, vector_phi);
0266       pack_into_bits(ret, start, scalar_pt);
0267       return ret;
0268     }
0269 
0270     inline uint64_t pack() const {
0271       ap_uint<BITWIDTH> x = pack_ap();
0272       return (uint64_t)x;
0273     }
0274 
0275     inline static Sum unpack_ap(const ap_uint<BITWIDTH> &src) {
0276       Sum ret;
0277       ret.initFromBits(src);
0278       return ret;
0279     }
0280 
0281     inline static Sum unpack(const uint64_t &src) { return unpack_ap(src); }
0282 
0283     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0284       unsigned int start = 0;
0285       unpack_from_bits(src, start, valid);
0286       unpack_from_bits(src, start, vector_pt);
0287       unpack_from_bits(src, start, vector_phi);
0288       unpack_from_bits(src, start, scalar_pt);
0289     }
0290   };  // struct Sum
0291 
0292   struct Tau {
0293     valid_t valid;
0294     ThreeVector v3;
0295     tauseed_pt_t seed_pt;
0296     z0_t seed_z0;
0297     ap_uint<1> charge;
0298     ap_uint<2> type;
0299     tau_quality_t quality;
0300     ap_uint<2> id0;
0301     ap_uint<2> id1;
0302 
0303     static const int BITWIDTH = 128;
0304     inline ap_uint<BITWIDTH> pack_ap() const {
0305       ap_uint<BITWIDTH> ret(0);
0306       unsigned int start = 0;
0307       pack_into_bits(ret, start, valid);
0308       pack_into_bits(ret, start, v3.pack());
0309       pack_into_bits(ret, start, seed_pt);
0310       pack_into_bits(ret, start, seed_z0);
0311       pack_into_bits(ret, start, charge);
0312       pack_into_bits(ret, start, type);
0313       pack_into_bits(ret, start, quality);
0314       pack_into_bits(ret, start, id0);
0315       pack_into_bits(ret, start, id1);
0316       return ret;
0317     }
0318 
0319     inline PackedTau pack() const {
0320       PackedTau packed;
0321       ap_uint<BITWIDTH> bits = this->pack_ap();
0322       packed[0] = bits(63, 0);
0323       packed[1] = bits(127, 64);
0324       return packed;
0325     }
0326 
0327     inline static Tau unpack_ap(const ap_uint<BITWIDTH> &src) {
0328       Tau ret;
0329       ret.initFromBits(src);
0330       return ret;
0331     }
0332 
0333     inline static Tau unpack(const PackedTau &src) {
0334       ap_uint<BITWIDTH> bits;
0335       bits(63, 0) = src[0];
0336       bits(127, 64) = src[1];
0337 
0338       return unpack_ap(bits);
0339     }
0340 
0341     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0342       unsigned int start = 0;
0343       unpack_from_bits(src, start, valid);
0344       unpack_from_bits(src, start, v3.pt);
0345       unpack_from_bits(src, start, v3.phi);
0346       unpack_from_bits(src, start, v3.eta);
0347       unpack_from_bits(src, start, seed_pt);
0348       unpack_from_bits(src, start, seed_z0);
0349       unpack_from_bits(src, start, charge);
0350       unpack_from_bits(src, start, type);
0351       unpack_from_bits(src, start, quality);
0352       unpack_from_bits(src, start, id0);
0353       unpack_from_bits(src, start, id1);
0354     }
0355 
0356   };  // struct Tau
0357 
0358   struct Electron {
0359     valid_t valid;
0360     ThreeVector v3;
0361     egquality_t qualityFlags;
0362     ap_uint<1> charge;
0363     z0_t z0;
0364     iso_t isolationPT;
0365 
0366     static const int BITWIDTH = 96;
0367     inline ap_uint<BITWIDTH> pack() const {
0368       ap_uint<BITWIDTH> ret(0);
0369       unsigned int start = 0;
0370       pack_into_bits(ret, start, valid);
0371       pack_into_bits(ret, start, v3.pack());
0372       pack_into_bits(ret, start, qualityFlags);
0373       pack_into_bits(ret, start, isolationPT);
0374       pack_into_bits(ret, start, charge);
0375       pack_into_bits(ret, start, z0);
0376       return ret;
0377     }
0378 
0379     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0380       unsigned int start = 0;
0381       unpack_from_bits(src, start, valid);
0382       unpack_from_bits(src, start, v3.pt);
0383       unpack_from_bits(src, start, v3.phi);
0384       unpack_from_bits(src, start, v3.eta);
0385       unpack_from_bits(src, start, qualityFlags);
0386       unpack_from_bits(src, start, isolationPT);
0387       unpack_from_bits(src, start, charge);
0388       unpack_from_bits(src, start, z0);
0389     }
0390 
0391     inline static Electron unpack_ap(const ap_uint<BITWIDTH> &src) {
0392       Electron ret;
0393       ret.initFromBits(src);
0394       return ret;
0395     }
0396 
0397     inline static Electron unpack(const std::array<uint64_t, 2> &src, int parity) {
0398       ap_uint<BITWIDTH> bits;
0399       if (parity == 0) {
0400         bits(63, 0) = src[0];
0401         bits(95, 64) = src[1];
0402       } else {
0403         bits(63, 0) = src[1];
0404         bits(95, 64) = (src[0] >> 32);
0405       }
0406       return unpack_ap(bits);
0407     }
0408   };
0409 
0410   struct Photon {
0411     valid_t valid;
0412     ThreeVector v3;
0413     egquality_t qualityFlags;
0414     iso_t isolationPT;
0415 
0416     static const int BITWIDTH = 96;
0417     inline ap_uint<BITWIDTH> pack() const {
0418       ap_uint<96> ret(0);
0419       unsigned int start = 0;
0420       pack_into_bits(ret, start, valid);
0421       pack_into_bits(ret, start, v3.pack());
0422       pack_into_bits(ret, start, qualityFlags);
0423       pack_into_bits(ret, start, isolationPT);
0424       return ret;
0425     }
0426 
0427     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0428       unsigned int start = 0;
0429       unpack_from_bits(src, start, valid);
0430       unpack_from_bits(src, start, v3.pt);
0431       unpack_from_bits(src, start, v3.phi);
0432       unpack_from_bits(src, start, v3.eta);
0433       unpack_from_bits(src, start, qualityFlags);
0434       unpack_from_bits(src, start, isolationPT);
0435     }
0436 
0437     inline static Photon unpack_ap(const ap_uint<BITWIDTH> &src) {
0438       Photon ret;
0439       ret.initFromBits(src);
0440       return ret;
0441     }
0442 
0443     inline static Photon unpack(const std::array<uint64_t, 2> &src, int parity) {
0444       ap_uint<BITWIDTH> bits(0);
0445       if (parity == 0) {
0446         bits(63, 0) = src[0];
0447         bits(95, 64) = src[1];
0448       } else {
0449         bits(63, 0) = src[1];
0450         bits(95, 64) = (src[0] >> 32);
0451       }
0452       return unpack_ap(bits);
0453     }
0454   };
0455 
0456 }  // namespace l1gt
0457 
0458 namespace l1ct {
0459 
0460   typedef ap_fixed<18, 5, AP_RND_CONV, AP_SAT> etaphi_sf_t;  // use a DSP input width
0461 
0462   namespace Scales {
0463     const etaphi_sf_t ETAPHI_CTtoGT_SCALE = (Scales::ETAPHI_LSB / l1gt::Scales::ETAPHI_LSB);
0464   }
0465 
0466   inline l1gt::pt_t CTtoGT_pt(pt_t x) {
0467     // the CT & GT pT are both ap_fixed with different power-of-2 LSBs
0468     // -> conversion is just a cast
0469     return (l1gt::pt_t)x;
0470   }
0471 
0472   inline l1gt::eta_t CTtoGT_eta(glbeta_t x) {
0473     // rescale the eta into the GT coordinates
0474     return x * Scales::ETAPHI_CTtoGT_SCALE;
0475   }
0476 
0477   inline l1gt::phi_t CTtoGT_phi(glbphi_t x) {
0478     // rescale the phi into the GT coordinates
0479     return x * Scales::ETAPHI_CTtoGT_SCALE;
0480   }
0481 
0482   inline l1gt::mass2_t CTtoGT_massSq(mass2_t x) { return (l1gt::mass2_t)x; }
0483 
0484 }  // namespace l1ct
0485 
0486 #endif