Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_L1TParticleFlow_PFCluster_h
0002 #define DataFormats_L1TParticleFlow_PFCluster_h
0003 
0004 #include <vector>
0005 #include <variant>
0006 #include "DataFormats/L1Trigger/interface/L1Candidate.h"
0007 #include "DataFormats/Common/interface/Ref.h"
0008 #include "DataFormats/L1TParticleFlow/interface/layer1_objs.h"
0009 #include <ap_int.h>
0010 
0011 namespace l1t {
0012 
0013   class PFCluster : public L1Candidate {
0014   public:
0015     /// constituent information. note that this is not going to be available in the hardware!
0016     typedef std::pair<edm::Ptr<l1t::L1Candidate>, float> ConstituentAndFraction;
0017     typedef std::vector<ConstituentAndFraction> ConstituentsAndFractions;
0018 
0019     PFCluster() {}
0020     PFCluster(float pt,
0021               float eta,
0022               float phi,
0023               float hOverE = 0,
0024               bool isEM = false,
0025               float ptError = 0,
0026               int hwpt = 0,
0027               int hweta = 0,
0028               int hwphi = 0)
0029         : L1Candidate(PolarLorentzVector(pt, eta, phi, 0), hwpt, hweta, hwphi, /*hwQuality=*/isEM ? 1 : 0),
0030           hOverE_(hOverE),
0031           ptError_(ptError),
0032           encoding_(HWEncoding::None),
0033           digiDataW0_(0),
0034           digiDataW1_(0) {
0035       setPdgId(isEM ? 22 : 130);  // photon : non-photon(K0)
0036     }
0037     PFCluster(
0038         const LorentzVector& p4, float hOverE, bool isEM, float ptError = 0, int hwpt = 0, int hweta = 0, int hwphi = 0)
0039         : L1Candidate(p4, hwpt, hweta, hwphi, /*hwQuality=*/isEM ? 1 : 0), hOverE_(hOverE), ptError_(ptError) {
0040       setPdgId(isEM ? 22 : 130);  // photon : non-photon(K0)
0041     }
0042 
0043     enum class HWEncoding { None = 0, Had = 1, Em = 2 };
0044 
0045     float hOverE() const { return hOverE_; }
0046     void setHOverE(float hOverE) { hOverE_ = hOverE; }
0047 
0048     // NOTE: this might not be consistent with the value stored in the HW digi
0049     float emEt() const {
0050       if (hOverE_ == -1)
0051         return 0;
0052       return pt() / (1 + hOverE_);
0053     }
0054 
0055     // change the pt. H/E also recalculated to keep emEt constant
0056     void calibratePt(float newpt, float preserveEmEt = true);
0057 
0058     /// constituent information. note that this is not going to be available in the hardware!
0059     const ConstituentsAndFractions& constituentsAndFractions() const { return constituents_; }
0060     /// adds a candidate to this cluster; note that this only records the information, it's up to you to also set the 4-vector appropriately
0061     void addConstituent(const edm::Ptr<l1t::L1Candidate>& cand, float fraction = 1.0) {
0062       constituents_.emplace_back(cand, fraction);
0063     }
0064 
0065     float ptError() const { return ptError_; }
0066     void setPtError(float ptError) { ptError_ = ptError; }
0067 
0068     bool isEM() const { return hwQual(); }
0069     void setIsEM(bool isEM) { setHwQual(isEM); }
0070     unsigned int hwEmID() const { return hwQual(); }
0071 
0072     std::variant<l1ct::HadCaloObj, l1ct::EmCaloObj> caloDigiObj() const {
0073       switch (encoding_) {
0074         case HWEncoding::Had:
0075           return l1ct::HadCaloObj::unpack(binaryWord<l1ct::HadCaloObj::BITWIDTH>());
0076         case HWEncoding::Em:
0077           return l1ct::EmCaloObj::unpack(binaryWord<l1ct::EmCaloObj::BITWIDTH>());
0078         default:
0079           throw std::runtime_error("No encoding for this cluster");
0080       }
0081     }
0082 
0083     void setCaloDigi(const l1ct::HadCaloObj& obj) { setBinaryWord(obj.pack(), HWEncoding::Had); }
0084 
0085     void setCaloDigi(const l1ct::EmCaloObj& obj) { setBinaryWord(obj.pack(), HWEncoding::Em); }
0086 
0087     HWEncoding encoding() const { return encoding_; }
0088 
0089   private:
0090     float hOverE_, ptError_;
0091 
0092     ConstituentsAndFractions constituents_;
0093 
0094     template <int N>
0095     void setBinaryWord(ap_uint<N> word, HWEncoding encoding) {
0096       digiDataW0_ = word;
0097       digiDataW1_ = (word >> 64);
0098       encoding_ = encoding;
0099     }
0100 
0101     template <int N>
0102     ap_uint<N> binaryWord() const {
0103       return ap_uint<N>(digiDataW0_) | (ap_uint<N>(digiDataW1_) << 64);
0104     }
0105 
0106     HWEncoding encoding_;
0107     uint64_t digiDataW0_;
0108     uint64_t digiDataW1_;
0109   };
0110 
0111   typedef std::vector<l1t::PFCluster> PFClusterCollection;
0112   typedef edm::Ref<l1t::PFClusterCollection> PFClusterRef;
0113 }  // namespace l1t
0114 #endif