Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_L1TParticleFlow_jets_h
0002 #define DataFormats_L1TParticleFlow_jets_h
0003 
0004 #include "DataFormats/L1TParticleFlow/interface/datatypes.h"
0005 #include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h"
0006 #include "DataFormats/L1TParticleFlow/interface/bit_encoding.h"
0007 #include <array>
0008 #include <algorithm>
0009 #include <cstdint>
0010 #include <vector>
0011 #include <unordered_map>
0012 
0013 namespace l1ct {
0014 
0015   // all possible tag categories (can be extended for new / separate taggers)
0016   class JetTagClass {
0017   public:
0018     enum JetTagClassValue : uint8_t { b, c, uds, g, tau_p, tau_n, mu, e };
0019     JetTagClass() = default;
0020     JetTagClass(JetTagClassValue aJetTagClassValue) : value_(aJetTagClassValue) {}
0021     JetTagClass(std::string aJetTagClassValueString) {
0022       auto it = labels_.find(aJetTagClassValueString);
0023       if (it != labels_.end()) {
0024         value_ = it->second;
0025       } else {
0026         // TODO throw an error
0027         value_ = JetTagClass::JetTagClassValue::uds;
0028       }
0029     }
0030 
0031     inline bool operator==(const JetTagClass &other) const { return value_ == other.value_; }
0032 
0033   private:
0034     JetTagClassValue value_;
0035     static const std::unordered_map<std::string, JetTagClassValue> labels_;
0036 
0037     friend std::ostream &operator<<(std::ostream &ost, const l1ct::JetTagClass &jtc) {
0038       auto it = std::find_if(
0039           std::begin(jtc.labels_), std::end(jtc.labels_), [&jtc](auto &&p) { return p.second == jtc.value_; });
0040       if (it != std::end(jtc.labels_)) {
0041         ost << it->first;
0042       }
0043       return ost;
0044     }
0045 
0046   };  // JetTagClass
0047 
0048   // Define a separate class/struct for jet tag handling
0049   struct JetTagClassHandler {
0050     static const unsigned NTagFields = 8;
0051     static const JetTagClass tagClassesDefault_[NTagFields];
0052 
0053     JetTagClass tagClassesArray[NTagFields];
0054 
0055     JetTagClassHandler() {
0056       // Copy the default values to the array
0057       for (unsigned i = 0; i < NTagFields; i++) {
0058         tagClassesArray[i] = tagClassesDefault_[i];
0059       }
0060     }
0061   };
0062 
0063   struct Jet {
0064     pt_t hwPt;
0065     glbeta_t hwEta;
0066     glbphi_t hwPhi;
0067     z0_t hwZ0;
0068 
0069     static const unsigned NTagFields = 8;
0070     jet_tag_score_t hwTagScores[NTagFields];
0071     mass2_t hwMassSq;
0072 
0073     inline bool operator==(const Jet &other) const {
0074       bool eq = hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwMassSq == other.hwMassSq &&
0075                 hwZ0 == other.hwZ0;
0076       for (unsigned i = 0; i < NTagFields; i++) {
0077         eq = eq && hwTagScores[i] == other.hwTagScores[i];
0078       }
0079       return eq;
0080     }
0081 
0082     inline bool operator>(const Jet &other) const { return hwPt > other.hwPt; }
0083     inline bool operator<(const Jet &other) const { return hwPt < other.hwPt; }
0084 
0085     inline void clear() {
0086       hwPt = 0;
0087       hwEta = 0;
0088       hwPhi = 0;
0089       hwMassSq = 0;
0090       hwZ0 = 0;
0091       for (unsigned i = 0; i < NTagFields; i++) {
0092         hwTagScores[i] = 0;
0093       }
0094     }
0095 
0096     int intPt() const { return Scales::intPt(hwPt); }
0097     int intEta() const { return hwEta.to_int(); }
0098     int intPhi() const { return hwPhi.to_int(); }
0099     float floatPt() const { return Scales::floatPt(hwPt); }
0100     float floatEta() const { return Scales::floatEta(hwEta); }
0101     float floatPhi() const { return Scales::floatPhi(hwPhi); }
0102     float floatZ0() const { return Scales::floatZ0(hwZ0); }
0103     float floatMass() const { return Scales::floatMass(hwMassSq); }
0104     std::vector<float> floatIDScores() const {
0105       std::vector<float> scores(NTagFields);
0106       for (unsigned i = 0; i < NTagFields; i++) {
0107         scores[i] = (float)hwTagScores[i];
0108       }
0109       return scores;
0110     }
0111 
0112     static const int BITWIDTH =
0113         pt_t::width + glbeta_t::width + glbphi_t::width + mass2_t::width + z0_t::width + NTagFields * id_score_t::width;
0114 
0115     inline ap_uint<BITWIDTH> pack_ap() const {
0116       ap_uint<BITWIDTH> ret;
0117       unsigned int start = 0;
0118       pack_into_bits(ret, start, hwPt);
0119       pack_into_bits(ret, start, hwEta);
0120       pack_into_bits(ret, start, hwPhi);
0121       pack_into_bits(ret, start, hwMassSq);
0122       pack_into_bits(ret, start, hwZ0);
0123       for (unsigned i = 0; i < NTagFields; i++) {
0124         pack_into_bits(ret, start, hwTagScores[i]);
0125       }
0126       return ret;
0127     }
0128 
0129     inline std::array<uint64_t, 2> pack() const {
0130       std::array<uint64_t, 2> packed = {{0, 0}};
0131       ap_uint<BITWIDTH> bits = this->pack_ap();
0132       packed[0] = bits(63, 0);
0133       packed[1] = bits(BITWIDTH - 1, 64);  // for when there are more than 64 bits in the word
0134       return packed;
0135     }
0136 
0137     inline static Jet unpack_ap(const ap_uint<BITWIDTH> &src) {
0138       Jet ret;
0139       ret.initFromBits(src);
0140       return ret;
0141     }
0142 
0143     inline void initFromBits(const ap_uint<BITWIDTH> &src) {
0144       unsigned int start = 0;
0145       unpack_from_bits(src, start, hwPt);
0146       unpack_from_bits(src, start, hwEta);
0147       unpack_from_bits(src, start, hwPhi);
0148       unpack_from_bits(src, start, hwZ0);
0149       unpack_from_bits(src, start, hwMassSq);
0150       for (unsigned i = 0; i < NTagFields; i++) {
0151         unpack_from_bits(src, start, hwTagScores[i]);
0152       }
0153     }
0154 
0155     inline static Jet unpack(const std::array<uint64_t, 2> &src) {
0156       // just one set while the word has fewer than 64 bits
0157       ap_uint<BITWIDTH> bits;
0158       bits(63, 0) = src[0];
0159       bits(BITWIDTH - 1, 64) = src[1];
0160       return unpack_ap(bits);
0161     }
0162 
0163     inline static Jet unpack(long long unsigned int &src) {
0164       // unpack from single 64b int
0165       ap_uint<BITWIDTH> bits = src;
0166       return unpack_ap(bits);
0167     }
0168 
0169     inline static Jet unpack(const std::array<long long unsigned int, 2> &src) {
0170       // unpack from two 64b ints
0171       ap_uint<BITWIDTH> bits;
0172       bits(63, 0) = src[0];
0173       // bits(127, 64) = src[1];
0174       return unpack_ap(bits);
0175     }
0176 
0177     l1gt::Jet toGT() const {
0178       l1gt::Jet j;
0179       j.valid = hwPt != 0;
0180       j.v3.pt = CTtoGT_pt(hwPt);
0181       j.v3.phi = CTtoGT_phi(hwPhi);
0182       j.v3.eta = CTtoGT_eta(hwEta);
0183       j.z0(l1ct::z0_t::width - 1, 0) = hwZ0(l1ct::z0_t::width - 1, 0);
0184       for (unsigned i = 0; i < NTagFields; i++) {
0185         j.hwTagScores[i] = hwTagScores[i];
0186       }
0187       return j;
0188     }
0189 
0190     l1gt::WideJet toGTWide() const {
0191       l1gt::WideJet j;
0192       j.valid = hwPt != 0;
0193       j.v3.pt = CTtoGT_pt(hwPt);
0194       j.v3.phi = CTtoGT_phi(hwPhi);
0195       j.v3.eta = CTtoGT_eta(hwEta);
0196       j.z0(l1ct::z0_t::width - 1, 0) = hwZ0(l1ct::z0_t::width - 1, 0);
0197       j.hwNProngScore = 0;
0198       j.hwMassSq = CTtoGT_massSq(hwMassSq);
0199 
0200       return j;
0201     }
0202   };
0203 
0204   inline void clear(Jet &c) { c.clear(); }
0205 
0206 }  // namespace l1ct
0207 
0208 #endif