Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0002 #include <cmath>
0003 #include <iostream>
0004 #include <cstdlib>
0005 #include <algorithm>
0006 
0007 #ifdef CMSSW_GIT_HASH
0008 #include "DataFormats/Math/interface/deltaPhi.h"
0009 #else
0010 namespace reco {
0011   template <typename T>
0012   inline T reducePhiRange(T x) {
0013     T o2pi = 1. / (2. * M_PI);
0014     if (std::abs(x) <= T(M_PI))
0015       return x;
0016     T n = std::round(x * o2pi);
0017     return x - n * T(2. * M_PI);
0018   }
0019   inline double deltaPhi(double phi1, double phi2) { return reducePhiRange(phi1 - phi2); }
0020 }  // namespace reco
0021 #endif
0022 
0023 bool l1ct::HadCaloObjEmu::read(std::fstream& from) {
0024   src = nullptr;  // not persistent
0025   return readObj<HadCaloObj>(from, *this);
0026 }
0027 bool l1ct::HadCaloObjEmu::write(std::fstream& to) const { return writeObj<HadCaloObj>(*this, to); }
0028 
0029 bool l1ct::EmCaloObjEmu::read(std::fstream& from) {
0030   src = nullptr;  // not persistent
0031   return readObj<EmCaloObj>(from, *this);
0032 }
0033 bool l1ct::EmCaloObjEmu::write(std::fstream& to) const { return writeObj<EmCaloObj>(*this, to); }
0034 
0035 bool l1ct::TkObjEmu::read(std::fstream& from) {
0036   src = nullptr;  // not persistent
0037   return readObj<TkObj>(from, *this) && readVar(from, hwChi2) && readVar(from, simPt) && readVar(from, simCaloEta) &&
0038          readVar(from, simCaloPhi) && readVar(from, simVtxEta) && readVar(from, simVtxPhi) && readVar(from, simZ0) &&
0039          readVar(from, simD0);
0040 }
0041 bool l1ct::TkObjEmu::write(std::fstream& to) const {
0042   return writeObj<TkObj>(*this, to) && writeVar(hwChi2, to) && writeVar(simPt, to) && writeVar(simCaloEta, to) &&
0043          writeVar(simCaloPhi, to) && writeVar(simVtxEta, to) && writeVar(simVtxPhi, to) && writeVar(simZ0, to) &&
0044          writeVar(simD0, to);
0045 }
0046 
0047 bool l1ct::MuObjEmu::read(std::fstream& from) {
0048   src = nullptr;  // not persistent
0049   return readObj<MuObj>(from, *this);
0050 }
0051 bool l1ct::MuObjEmu::write(std::fstream& to) const { return writeObj<MuObj>(*this, to); }
0052 
0053 bool l1ct::PFChargedObjEmu::read(std::fstream& from) {
0054   srcTrack = nullptr;    // not persistent
0055   srcCluster = nullptr;  // not persistent
0056   srcMu = nullptr;       // not persistent
0057   srcCand = nullptr;     // not persistent
0058   return readObj<PFChargedObj>(from, *this);
0059 }
0060 bool l1ct::PFChargedObjEmu::write(std::fstream& to) const { return writeObj<PFChargedObj>(*this, to); }
0061 
0062 bool l1ct::PFNeutralObjEmu::read(std::fstream& from) {
0063   srcCluster = nullptr;  // not persistent
0064   srcCand = nullptr;     // not persistent
0065   return readObj<PFNeutralObj>(from, *this);
0066 }
0067 bool l1ct::PFNeutralObjEmu::write(std::fstream& to) const { return writeObj<PFNeutralObj>(*this, to); }
0068 
0069 bool l1ct::PuppiObjEmu::read(std::fstream& from) {
0070   srcTrack = nullptr;    // not persistent
0071   srcCluster = nullptr;  // not persistent
0072   srcMu = nullptr;       // not persistent
0073   srcCand = nullptr;     // not persistent
0074   return readObj<PuppiObj>(from, *this);
0075 }
0076 bool l1ct::PuppiObjEmu::write(std::fstream& to) const { return writeObj<PuppiObj>(*this, to); }
0077 
0078 bool l1ct::EGIsoObjEmu::read(std::fstream& from) {
0079   srcCluster = nullptr;  // not persistent
0080   src_idx = -1;
0081   clearIsoVars();  // not persistent
0082   return readObj<EGIsoObj>(from, *this);
0083 }
0084 
0085 bool l1ct::EGIsoObjEmu::write(std::fstream& to) const { return writeObj<EGIsoObj>(*this, to); }
0086 
0087 bool l1ct::EGIsoEleObjEmu::read(std::fstream& from) {
0088   srcCluster = nullptr;
0089   srcTrack = nullptr;
0090   src_idx = -1;
0091   clearIsoVars();  // not persistent
0092   return readObj<EGIsoEleObj>(from, *this);
0093 }
0094 
0095 bool l1ct::EGIsoEleObjEmu::write(std::fstream& to) const { return writeObj<EGIsoEleObj>(*this, to); }
0096 
0097 l1ct::PFRegionEmu::PFRegionEmu(float etaCenter, float phicenter) {
0098   hwEtaCenter = Scales::makeGlbEta(etaCenter);
0099   hwPhiCenter = Scales::makeGlbPhi(phicenter);
0100   hwEtaHalfWidth = 0;
0101   hwPhiHalfWidth = 0;
0102   hwEtaExtra = 0;
0103   hwPhiExtra = 0;
0104 }
0105 l1ct::PFRegionEmu::PFRegionEmu(
0106     float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra) {
0107   glbeta_t hwEtaMin = Scales::makeGlbEtaRoundEven(etamin);
0108   glbeta_t hwEtaMax = Scales::makeGlbEtaRoundEven(etamax);
0109 
0110   hwEtaCenter = glbeta_t((hwEtaMin + hwEtaMax) / 2);
0111   hwPhiCenter = Scales::makeGlbPhi(phicenter);
0112   hwEtaHalfWidth = hwEtaCenter - hwEtaMin;
0113   hwPhiHalfWidth = Scales::makeGlbPhi(0.5 * phiwidth);
0114   hwEtaExtra = Scales::makeGlbEta(etaextra);
0115   hwPhiExtra = Scales::makeGlbPhi(phiextra);
0116 }
0117 
0118 bool l1ct::PFRegionEmu::contains(float eta, float phi) const {
0119   float dphi = reco::deltaPhi(phi, floatPhiCenter());
0120   return (floatEtaMinExtra() <= eta && eta <= floatEtaMaxExtra() && -floatPhiHalfWidthExtra() <= dphi &&
0121           dphi <= floatPhiHalfWidthExtra());
0122 }
0123 bool l1ct::PFRegionEmu::containsHw(glbeta_t glbeta, glbphi_t glbphi) const {
0124   glbeta_t loceta = glbeta - hwEtaCenter;
0125   ap_int<glbphi_t::width + 1> locphi = glbphi - hwPhiCenter;
0126   if (locphi > Scales::INTPHI_PI)
0127     locphi -= Scales::INTPHI_TWOPI;
0128   else if (locphi <= -Scales::INTPHI_PI)
0129     locphi += Scales::INTPHI_TWOPI;
0130   return isInside(loceta, locphi);
0131 }
0132 
0133 float l1ct::PFRegionEmu::localEta(float globalEta) const { return globalEta - floatEtaCenter(); }
0134 float l1ct::PFRegionEmu::localPhi(float globalPhi) const { return reco::deltaPhi(globalPhi, floatPhiCenter()); }
0135 
0136 bool l1ct::PFRegionEmu::read(std::fstream& from) { return readObj<PFRegion>(from, *this); }
0137 bool l1ct::PFRegionEmu::write(std::fstream& to) const { return writeObj<PFRegion>(*this, to); }
0138 
0139 bool l1ct::PVObjEmu::read(std::fstream& from) { return readObj<PVObj>(from, *this); }
0140 bool l1ct::PVObjEmu::write(std::fstream& to) const { return writeObj<PVObj>(*this, to); }
0141 
0142 bool l1ct::RawInputs::read(std::fstream& from) {
0143   uint32_t number;
0144 
0145   if (!readVar(from, number))
0146     return false;
0147   track.resize(number);
0148   for (auto& v : track) {
0149     if (!(v.region.read(from) && readMany(from, v.obj)))
0150       return false;
0151   }
0152 
0153   if (!(muon.region.read(from) && readMany(from, muon.obj)))
0154     return false;
0155 
0156   if (!readVar(from, number))
0157     return false;
0158   hgcalcluster.resize(number);
0159   for (auto& v : hgcalcluster) {
0160     if (!(v.region.read(from) && readMany(from, v.obj)))
0161       return false;
0162   }
0163 
0164   if (!readVar(from, number))
0165     return false;
0166   gctHad.resize(number);
0167   for (auto& v : gctHad) {
0168     if (!(v.region.read(from) && readMany(from, v.obj)))
0169       return false;
0170   }
0171 
0172   if (!readVar(from, number))
0173     return false;
0174   gctEm.resize(number);
0175   for (auto& v : gctEm) {
0176     if (!(v.region.read(from) && readMany(from, v.obj)))
0177       return false;
0178   }
0179 
0180   return true;
0181 }
0182 
0183 bool l1ct::RawInputs::write(std::fstream& to) const {
0184   uint32_t number;
0185 
0186   number = track.size();
0187   if (!writeVar(number, to))
0188     return false;
0189   for (const auto& v : track) {
0190     if (!(v.region.write(to) && writeMany(v.obj, to)))
0191       return false;
0192   }
0193 
0194   if (!(muon.region.write(to) && writeMany(muon.obj, to)))
0195     return false;
0196 
0197   number = hgcalcluster.size();
0198   if (!writeVar(number, to))
0199     return false;
0200   for (const auto& v : hgcalcluster) {
0201     if (!(v.region.write(to) && writeMany(v.obj, to)))
0202       return false;
0203   }
0204 
0205   number = gctHad.size();
0206   if (!writeVar(number, to))
0207     return false;
0208   for (const auto& v : gctHad) {
0209     if (!(v.region.write(to) && writeMany(v.obj, to)))
0210       return false;
0211   }
0212 
0213   number = gctEm.size();
0214   if (!writeVar(number, to))
0215     return false;
0216   for (const auto& v : gctEm) {
0217     if (!(v.region.write(to) && writeMany(v.obj, to)))
0218       return false;
0219   }
0220   return true;
0221 }
0222 void l1ct::RawInputs::clear() {
0223   for (auto& r : track)
0224     r.clear();
0225   muon.clear();
0226   for (auto& h : hgcalcluster)
0227     h.clear();
0228   for (auto& h : gctHad)
0229     h.clear();
0230   for (auto& h : gctEm)
0231     h.clear();
0232 }
0233 
0234 bool l1ct::RegionizerDecodedInputs::read(std::fstream& from) {
0235   uint32_t number;
0236 
0237   if (!readVar(from, number))
0238     return false;
0239   hadcalo.resize(number);
0240   for (auto& v : hadcalo) {
0241     if (!(v.region.read(from) && readMany(from, v.obj)))
0242       return false;
0243   }
0244 
0245   if (!readVar(from, number))
0246     return false;
0247   emcalo.resize(number);
0248   for (auto& v : emcalo) {
0249     if (!(v.region.read(from) && readMany(from, v.obj)))
0250       return false;
0251   }
0252 
0253   if (!readVar(from, number))
0254     return false;
0255   track.resize(number);
0256   for (auto& v : track) {
0257     if (!(v.region.read(from) && readMany(from, v.obj)))
0258       return false;
0259   }
0260 
0261   if (!(muon.region.read(from) && readMany(from, muon.obj)))
0262     return false;
0263 
0264   return true;
0265 }
0266 
0267 bool l1ct::RegionizerDecodedInputs::write(std::fstream& to) const {
0268   uint32_t number;
0269 
0270   number = hadcalo.size();
0271   if (!writeVar(number, to))
0272     return false;
0273   for (const auto& v : hadcalo) {
0274     if (!(v.region.write(to) && writeMany(v.obj, to)))
0275       return false;
0276   }
0277 
0278   number = emcalo.size();
0279   if (!writeVar(number, to))
0280     return false;
0281   for (const auto& v : emcalo) {
0282     if (!(v.region.write(to) && writeMany(v.obj, to)))
0283       return false;
0284   }
0285 
0286   number = track.size();
0287   if (!writeVar(number, to))
0288     return false;
0289   for (const auto& v : track) {
0290     if (!(v.region.write(to) && writeMany(v.obj, to)))
0291       return false;
0292   }
0293 
0294   if (!(muon.region.write(to) && writeMany(muon.obj, to)))
0295     return false;
0296 
0297   return true;
0298 }
0299 void l1ct::RegionizerDecodedInputs::clear() {
0300   for (auto& r : hadcalo)
0301     r.clear();
0302   for (auto& r : emcalo)
0303     r.clear();
0304   for (auto& r : track)
0305     r.clear();
0306   muon.clear();
0307 }
0308 
0309 bool l1ct::PFInputRegion::read(std::fstream& from) {
0310   return region.read(from) && readMany(from, hadcalo) && readMany(from, emcalo) && readMany(from, track) &&
0311          readMany(from, muon);
0312 }
0313 bool l1ct::PFInputRegion::write(std::fstream& to) const {
0314   return region.write(to) && writeMany(hadcalo, to) && writeMany(emcalo, to) && writeMany(track, to) &&
0315          writeMany(muon, to);
0316 }
0317 void l1ct::PFInputRegion::clear() {
0318   hadcalo.clear();
0319   emcalo.clear();
0320   track.clear();
0321   muon.clear();
0322 }
0323 
0324 bool l1ct::OutputRegion::read(std::fstream& from) {
0325   return readMany(from, pfcharged) && readMany(from, pfneutral) && readMany(from, pfphoton) && readMany(from, pfmuon) &&
0326          readMany(from, puppi) && readMany(from, egphoton) && readMany(from, egelectron);
0327 }
0328 bool l1ct::OutputRegion::write(std::fstream& to) const {
0329   return writeMany(pfcharged, to) && writeMany(pfneutral, to) && writeMany(pfphoton, to) && writeMany(pfmuon, to) &&
0330          writeMany(puppi, to) && writeMany(egphoton, to) && writeMany(egelectron, to);
0331 }
0332 
0333 void l1ct::OutputRegion::clear() {
0334   pfcharged.clear();
0335   pfphoton.clear();
0336   pfneutral.clear();
0337   pfmuon.clear();
0338   puppi.clear();
0339   egsta.clear();
0340   egphoton.clear();
0341   egelectron.clear();
0342 }
0343 
0344 // begin helper functions
0345 namespace {
0346   template <typename TV>
0347   unsigned int count_nonnull(const TV& v) {
0348     typedef typename TV::value_type T;
0349     return std::count_if(v.begin(), v.end(), [](const T& p) { return p.hwPt > 0; });
0350   }
0351   template <typename TV, typename F>
0352   unsigned int count_nonnull_if(const TV& v, F pred) {
0353     unsigned int n = 0;
0354     for (auto& p : v) {
0355       if (p.hwPt > 0 && pred(p.hwId))
0356         ++n;
0357     }
0358     return n;
0359   }
0360 }  // namespace
0361 // end helper functions
0362 unsigned int l1ct::OutputRegion::nObj(ObjType type, bool usePuppi) const {
0363   switch (type) {
0364     case anyType:
0365       if (usePuppi)
0366         return ::count_nonnull(puppi);
0367       else
0368         return ::count_nonnull(pfcharged) + ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral);
0369     case chargedType:
0370       if (usePuppi)
0371         return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.charged(); });
0372       else
0373         return ::count_nonnull(pfcharged);
0374     case neutralType:
0375       if (usePuppi)
0376         return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.neutral(); });
0377       else
0378         return ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral);
0379     case electronType:
0380       if (usePuppi)
0381         return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isElectron(); });
0382       else
0383         return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isElectron(); });
0384     case muonType:
0385       if (usePuppi)
0386         return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isMuon(); });
0387       else
0388         return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isMuon(); });
0389     case chargedHadronType:
0390       if (usePuppi)
0391         return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); });
0392       else
0393         return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); });
0394     case neutralHadronType:
0395       if (usePuppi)
0396         return ::count_nonnull_if(puppi,
0397                                   [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; });
0398       else
0399         return ::count_nonnull_if(pfneutral,
0400                                   [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; });
0401     case photonType:
0402       if (usePuppi)
0403         return ::count_nonnull_if(puppi,
0404                                   [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; });
0405       else
0406         return ::count_nonnull_if(pfneutral,
0407                                   [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; }) +
0408                ::count_nonnull_if(pfphoton,
0409                                   [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; });
0410     case egisoType:
0411       assert(!usePuppi);
0412       return ::count_nonnull(egphoton);
0413     case egisoeleType:
0414       assert(!usePuppi);
0415       return ::count_nonnull(egelectron);
0416     default:
0417       assert(false);
0418   }
0419 }
0420 
0421 bool l1ct::OutputBoard::read(std::fstream& from) {
0422   return readVar(from, eta) && readVar(from, phi) && readMany(from, egphoton) && readMany(from, egelectron);
0423 }
0424 bool l1ct::OutputBoard::write(std::fstream& to) const {
0425   return writeVar(eta, to) && writeVar(phi, to) && writeMany(egphoton, to) && writeMany(egelectron, to);
0426 }
0427 
0428 void l1ct::OutputBoard::clear() {
0429   egphoton.clear();
0430   egelectron.clear();
0431 }
0432 
0433 bool l1ct::Event::read(std::fstream& from) {
0434   uint32_t version;
0435   if (!readVar(from, version))
0436     return false;
0437   if (version != VERSION) {
0438     //dbgCout() << "ERROR: version mismatch between this code (" << VERSION << ") and dump file (" << version << ")."
0439     //          << std::endl;
0440     //dbgCerr() << "ERROR: version mismatch between this code (" << VERSION << ") and dump file (" << version << ")."
0441     //          << std::endl;
0442     abort();
0443   }
0444   return readVar(from, run) && readVar(from, lumi) && readVar(from, event) && raw.read(from) && decoded.read(from) &&
0445          readMany(from, pfinputs) && readMany(from, pvs) && readMany(from, pvs_emu) && readMany(from, out) &&
0446          readMany(from, board_out);
0447 }
0448 bool l1ct::Event::write(std::fstream& to) const {
0449   uint32_t version = VERSION;
0450   return writeVar(version, to) && writeVar(run, to) && writeVar(lumi, to) && writeVar(event, to) && raw.write(to) &&
0451          decoded.write(to) && writeMany(pfinputs, to) && writeMany(pvs, to) && writeMany(pvs_emu, to) &&
0452          writeMany(out, to) && writeMany(board_out, to);
0453 }
0454 void l1ct::Event::init(uint32_t arun, uint32_t alumi, uint64_t anevent) {
0455   clear();
0456   run = arun;
0457   lumi = alumi;
0458   event = anevent;
0459 }
0460 void l1ct::Event::clear() {
0461   run = 0;
0462   lumi = 0;
0463   event = 0;
0464   raw.clear();
0465   decoded.clear();
0466   for (auto& i : pfinputs)
0467     i.clear();
0468   pvs.clear();
0469   pvs_emu.clear();
0470   for (auto& i : out)
0471     i.clear();
0472   for (auto& i : board_out)
0473     i.clear();
0474 }