Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_L1TParticleFlow_layer1_emulator_h
0002 #define DataFormats_L1TParticleFlow_layer1_emulator_h
0003 
0004 #include <fstream>
0005 #include <vector>
0006 #include "DataFormats/L1TParticleFlow/interface/layer1_objs.h"
0007 #include "DataFormats/L1TParticleFlow/interface/pf.h"
0008 #include "DataFormats/L1TParticleFlow/interface/puppi.h"
0009 #include "DataFormats/L1TParticleFlow/interface/egamma.h"
0010 #include "DataFormats/L1TParticleFlow/interface/emulator_io.h"
0011 
0012 namespace l1t {
0013   class PFTrack;
0014   class PFCandidate;
0015   class L1Candidate;
0016   class SAMuon;
0017 }  // namespace l1t
0018 
0019 namespace l1ct {
0020 
0021   struct HadCaloObjEmu : public HadCaloObj {
0022     const l1t::L1Candidate *src = nullptr;
0023     bool read(std::fstream &from);
0024     bool write(std::fstream &to) const;
0025     void clear() {
0026       HadCaloObj::clear();
0027       src = nullptr;
0028     }
0029   };
0030 
0031   struct EmCaloObjEmu : public EmCaloObj {
0032     const l1t::L1Candidate *src = nullptr;
0033     bool read(std::fstream &from);
0034     bool write(std::fstream &to) const;
0035     void clear() {
0036       EmCaloObj::clear();
0037       src = nullptr;
0038     }
0039   };
0040 
0041   struct TkObjEmu : public TkObj {
0042     uint16_t hwChi2;
0043     float simPt, simCaloEta, simCaloPhi, simVtxEta, simVtxPhi, simZ0, simD0;
0044     const l1t::PFTrack *src = nullptr;
0045     bool read(std::fstream &from);
0046     bool write(std::fstream &to) const;
0047     void clear() {
0048       TkObj::clear();
0049       src = nullptr;
0050       hwChi2 = 0;
0051       simPt = 0;
0052       simCaloEta = 0;
0053       simCaloPhi = 0;
0054       simVtxEta = 0;
0055       simVtxPhi = 0;
0056       simZ0 = 0;
0057       simD0 = 0;
0058     }
0059   };
0060 
0061   struct MuObjEmu : public MuObj {
0062     const l1t::SAMuon *src = nullptr;
0063     bool read(std::fstream &from);
0064     bool write(std::fstream &to) const;
0065     void clear() {
0066       MuObj::clear();
0067       src = nullptr;
0068     }
0069   };
0070 
0071   struct PFChargedObjEmu : public PFChargedObj {
0072     const l1t::L1Candidate *srcCluster = nullptr;
0073     const l1t::PFTrack *srcTrack = nullptr;
0074     const l1t::SAMuon *srcMu = nullptr;
0075     const l1t::PFCandidate *srcCand = nullptr;
0076     bool read(std::fstream &from);
0077     bool write(std::fstream &to) const;
0078     void clear() {
0079       PFChargedObj::clear();
0080       srcCluster = nullptr;
0081       srcTrack = nullptr;
0082       srcMu = nullptr;
0083       srcCand = nullptr;
0084     }
0085   };
0086 
0087   struct PFNeutralObjEmu : public PFNeutralObj {
0088     const l1t::L1Candidate *srcCluster = nullptr;
0089     const l1t::PFCandidate *srcCand = nullptr;
0090     bool read(std::fstream &from);
0091     bool write(std::fstream &to) const;
0092     void clear() {
0093       PFNeutralObj::clear();
0094       srcCluster = nullptr;
0095       srcCand = nullptr;
0096     }
0097   };
0098 
0099   struct PFRegionEmu : public PFRegion {
0100     PFRegionEmu() : PFRegion() {}
0101     PFRegionEmu(float etaCenter, float phicenter);
0102     PFRegionEmu(float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra);
0103 
0104     // global coordinates
0105     bool contains(float eta, float phi) const;
0106     bool containsHw(glbeta_t glbeta, glbphi_t phi) const;
0107     float localEta(float globalEta) const;
0108     float localPhi(float globalPhi) const;
0109 
0110     bool read(std::fstream &from);
0111     bool write(std::fstream &to) const;
0112   };
0113 
0114   struct PuppiObjEmu : public PuppiObj {
0115     const l1t::L1Candidate *srcCluster = nullptr;
0116     const l1t::PFTrack *srcTrack = nullptr;
0117     const l1t::SAMuon *srcMu = nullptr;
0118     const l1t::PFCandidate *srcCand = nullptr;
0119     bool read(std::fstream &from);
0120     bool write(std::fstream &to) const;
0121     void clear() {
0122       PuppiObj::clear();
0123       srcCluster = nullptr;
0124       srcTrack = nullptr;
0125       srcMu = nullptr;
0126       srcCand = nullptr;
0127     }
0128     inline void fill(const PFRegionEmu &region, const PFChargedObjEmu &src) {
0129       PuppiObj::fill(region, src);
0130       srcCluster = src.srcCluster;
0131       srcTrack = src.srcTrack;
0132       srcMu = src.srcMu;
0133       srcCand = src.srcCand;
0134     }
0135     inline void fill(const PFRegionEmu &region, const PFNeutralObjEmu &src, pt_t puppiPt, puppiWgt_t puppiWgt) {
0136       PuppiObj::fill(region, src, puppiPt, puppiWgt);
0137       srcCluster = src.srcCluster;
0138       srcTrack = nullptr;
0139       srcMu = nullptr;
0140       srcCand = src.srcCand;
0141     }
0142     inline void fill(const PFRegionEmu &region, const HadCaloObjEmu &src, pt_t puppiPt, puppiWgt_t puppiWgt) {
0143       PuppiObj::fill(region, src, puppiPt, puppiWgt);
0144       srcCluster = src.src;
0145       srcTrack = nullptr;
0146       srcMu = nullptr;
0147       srcCand = nullptr;
0148     }
0149   };
0150 
0151   struct EGObjEmu : public EGIsoObj {
0152     const l1t::L1Candidate *srcCluster = nullptr;
0153     void clear() {
0154       srcCluster = nullptr;
0155       EGIsoObj::clear();
0156     }
0157   };
0158 
0159   struct EGIsoObjEmu : public EGIsoObj {
0160     const l1t::L1Candidate *srcCluster;
0161 
0162     // NOTE: we use an index to the persistable RefPtr when we reshuffle collections
0163     // this way we avoid complex object in the object interface which needs to be used in standalone programs
0164     int src_idx;
0165     bool read(std::fstream &from);
0166     bool write(std::fstream &to) const;
0167     void clear() {
0168       EGIsoObj::clear();
0169       srcCluster = nullptr;
0170       src_idx = -1;
0171       clearIsoVars();
0172     }
0173 
0174     void clearIsoVars() {
0175       hwIsoVars[0] = 0;
0176       hwIsoVars[1] = 0;
0177       hwIsoVars[2] = 0;
0178       hwIsoVars[3] = 0;
0179       hwIsoVars[4] = 0;
0180       hwIsoVars[5] = 0;
0181     }
0182 
0183     using EGIsoObj::floatIso;
0184 
0185     enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3, PuppiIso = 4, PuppiIsoPV = 5 };
0186 
0187     float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); }
0188     float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); }
0189     float hwIsoVar(IsoType type) const { return hwIsoVars[type]; }
0190     void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; }
0191 
0192     iso_t hwIsoVars[6];
0193   };
0194 
0195   struct EGIsoEleObjEmu : public EGIsoEleObj {
0196     const l1t::L1Candidate *srcCluster = nullptr;
0197     const l1t::PFTrack *srcTrack = nullptr;
0198 
0199     // NOTE: we use an index to the persistable RefPtr when we reshuffle collections
0200     // this way we avoid complex object in the object interface which needs to be used in standalone programs
0201     int src_idx;
0202     bool read(std::fstream &from);
0203     bool write(std::fstream &to) const;
0204     void clear() {
0205       EGIsoEleObj::clear();
0206       srcCluster = nullptr;
0207       srcTrack = nullptr;
0208       src_idx = -1;
0209       clearIsoVars();
0210     }
0211 
0212     void clearIsoVars() {
0213       hwIsoVars[0] = 0;
0214       hwIsoVars[1] = 0;
0215       hwIsoVars[2] = 0;
0216     }
0217 
0218     using EGIsoEleObj::floatIso;
0219 
0220     enum IsoType { TkIso = 0, PfIso = 1, PuppiIso = 2 };
0221 
0222     float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); }
0223     float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); }
0224     float hwIsoVar(IsoType type) const { return hwIsoVars[type]; }
0225     void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; }
0226 
0227     iso_t hwIsoVars[3];
0228   };
0229 
0230   struct PVObjEmu : public PVObj {
0231     bool read(std::fstream &from);
0232     bool write(std::fstream &to) const;
0233   };
0234 
0235   template <typename T>
0236   struct DetectorSector {
0237     PFRegionEmu region;
0238     std::vector<T> obj;
0239     DetectorSector() {}
0240     DetectorSector(float etamin, float etamax, float phicenter, float phiwidth, float etaextra = 0, float phiextra = 0)
0241         : region(etamin, etamax, phicenter, phiwidth, etaextra, phiextra) {}
0242     // convenience forwarding of some methods
0243     typedef typename std::vector<T>::const_iterator const_iterator;
0244     typedef typename std::vector<T>::iterator iterator;
0245     inline const T &operator[](unsigned int i) const { return obj[i]; }
0246     inline T &operator[](unsigned int i) { return obj[i]; }
0247     inline const_iterator begin() const { return obj.begin(); }
0248     inline iterator begin() { return obj.begin(); }
0249     inline const_iterator end() const { return obj.end(); }
0250     inline iterator end() { return obj.end(); }
0251     inline unsigned int size() const { return obj.size(); }
0252     inline void resize(unsigned int size) { obj.resize(size); }
0253     inline void clear() { obj.clear(); }
0254   };
0255 
0256   struct RawInputs {
0257     std::vector<DetectorSector<ap_uint<96>>> track;
0258     DetectorSector<ap_uint<64>> muon;  // muons are global
0259     std::vector<DetectorSector<ap_uint<256>>> hgcalcluster;
0260     std::vector<DetectorSector<ap_uint<64>>> gctHad;  // the 48 hadronic clusters from the GCT
0261     std::vector<DetectorSector<ap_uint<64>>> gctEm;   // the 36 EM clusters from the GCT
0262     // (The trigger towers that follow the clusters are not included in the above data)
0263 
0264     bool read(std::fstream &from);
0265     bool write(std::fstream &to) const;
0266     void clear();
0267   };
0268 
0269   struct RegionizerDecodedInputs {
0270     std::vector<DetectorSector<HadCaloObjEmu>> hadcalo;
0271     std::vector<DetectorSector<EmCaloObjEmu>> emcalo;
0272     std::vector<DetectorSector<TkObjEmu>> track;
0273     DetectorSector<MuObjEmu> muon;  // muons are global
0274 
0275     bool read(std::fstream &from);
0276     bool write(std::fstream &to) const;
0277     void clear();
0278   };
0279 
0280   struct PFInputRegion {
0281     PFRegionEmu region;
0282     std::vector<HadCaloObjEmu> hadcalo;
0283     std::vector<EmCaloObjEmu> emcalo;
0284     std::vector<TkObjEmu> track;
0285     std::vector<MuObjEmu> muon;
0286 
0287     PFInputRegion() {}
0288     PFInputRegion(float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra)
0289         : region(etamin, etamax, phicenter, phiwidth, etaextra, phiextra) {}
0290     bool read(std::fstream &from);
0291     bool write(std::fstream &to) const;
0292     void clear();
0293   };
0294 
0295   struct OutputRegion {
0296     std::vector<PFChargedObjEmu> pfcharged;
0297     std::vector<PFNeutralObjEmu> pfphoton;
0298     std::vector<PFNeutralObjEmu> pfneutral;
0299     std::vector<PFChargedObjEmu> pfmuon;
0300     std::vector<PuppiObjEmu> puppi;
0301     std::vector<EGObjEmu> egsta;
0302     std::vector<EGIsoObjEmu> egphoton;
0303     std::vector<EGIsoEleObjEmu> egelectron;
0304 
0305     bool read(std::fstream &from);
0306     bool write(std::fstream &to) const;
0307     void clear();
0308 
0309     // for multiplicities
0310     enum ObjType {
0311       anyType = 0,
0312       chargedType = 1,
0313       neutralType = 2,
0314       electronType = 3,
0315       muonType = 4,
0316       chargedHadronType = 5,
0317       neutralHadronType = 6,
0318       photonType = 7,
0319       nPFTypes = 8,
0320       egisoType = 8,
0321       egisoeleType = 9,
0322       nObjTypes = 10
0323     };
0324     static constexpr const char *objTypeName[nObjTypes] = {
0325         "", "Charged", "Neutral", "Electron", "Muon", "ChargedHadron", "NeutralHadron", "Photon", "EGIso", "EGIsoEle"};
0326     unsigned int nObj(ObjType type, bool puppi) const;
0327   };
0328 
0329   struct OutputBoard {
0330     float eta;
0331     float phi;
0332     // NOTE: region_index is not written to the dump file
0333     std::vector<unsigned int> region_index;
0334     std::vector<EGIsoObjEmu> egphoton;
0335     std::vector<EGIsoEleObjEmu> egelectron;
0336 
0337     bool read(std::fstream &from);
0338     bool write(std::fstream &to) const;
0339     void clear();
0340   };
0341 
0342   struct Event {
0343     enum { VERSION = 14 };
0344     uint32_t run, lumi;
0345     uint64_t event;
0346     RawInputs raw;
0347     RegionizerDecodedInputs decoded;
0348     std::vector<PFInputRegion> pfinputs;
0349     std::vector<PVObjEmu> pvs;
0350     std::vector<ap_uint<64>> pvs_emu;
0351     std::vector<OutputRegion> out;
0352     std::vector<OutputBoard> board_out;
0353 
0354     Event() : run(0), lumi(0), event(0) {}
0355 
0356     bool read(std::fstream &from);
0357     bool write(std::fstream &to) const;
0358     void clear();
0359     void init(uint32_t run, uint32_t lumi, uint64_t event);
0360     inline l1ct::PVObjEmu pv(unsigned int ipv = 0) const {
0361       l1ct::PVObjEmu ret;
0362       if (ipv < pvs.size())
0363         ret = pvs[ipv];
0364       else
0365         ret.clear();
0366       return ret;
0367     }
0368     inline ap_uint<64> pv_emu(unsigned int ipv = 0) const {
0369       ap_uint<64> ret = 0;
0370       if (ipv < pvs_emu.size())
0371         ret = pvs_emu[ipv];
0372       return ret;
0373     }
0374   };
0375 
0376   template <typename T1, typename T2>
0377   void toFirmware(const std::vector<T1> &in, unsigned int NMAX, T2 out[/*NMAX*/]) {
0378     unsigned int n = std::min<unsigned>(in.size(), NMAX);
0379     for (unsigned int i = 0; i < n; ++i)
0380       out[i] = in[i];
0381     for (unsigned int i = n; i < NMAX; ++i)
0382       out[i].clear();
0383   }
0384 
0385 }  // namespace l1ct
0386 
0387 #endif