File indexing completed on 2025-05-09 22:40:11
0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h"
0002
0003 L1SCJetEmu::L1SCJetEmu(bool debug, float coneSize, unsigned nJets)
0004 : debug_(debug),
0005 coneSize_(coneSize),
0006 nJets_(nJets),
0007 rCone2_(coneSize * coneSize / l1ct::Scales::ETAPHI_LSB / l1ct::Scales::ETAPHI_LSB) {
0008 init_invert_table<pt_t, inv_pt_t, N_table_inv_pt>(inv_pt_table_);
0009 }
0010
0011 L1SCJetEmu::detaphi_t L1SCJetEmu::deltaPhi(L1SCJetEmu::Particle a, L1SCJetEmu::Particle b) {
0012 detaphi_t dphi = detaphi_t(a.hwPhi) - detaphi_t(b.hwPhi);
0013
0014 detaphi_t dphi0 =
0015 dphi > detaphi_t(l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI - dphi) : detaphi_t(dphi);
0016 detaphi_t dphi1 =
0017 dphi < detaphi_t(-l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI + dphi) : detaphi_t(dphi);
0018 detaphi_t dphiw = dphi > detaphi_t(0) ? dphi0 : dphi1;
0019 return dphiw;
0020 }
0021
0022 bool L1SCJetEmu::inCone(L1SCJetEmu::Particle seed, L1SCJetEmu::Particle part) const {
0023
0024 detaphi_t deta = detaphi_t(seed.hwEta) - detaphi_t(part.hwEta);
0025 detaphi_t dphi = deltaPhi(seed, part);
0026 bool ret = deta * deta + dphi * dphi < rCone2_;
0027
0028 if (debug_) {
0029 detaphi2_t r2 = detaphi2_t(deta) * detaphi2_t(deta) + detaphi2_t(dphi) * detaphi2_t(dphi);
0030 dbgCout() << " part eta, seed eta: " << part.hwEta << ", " << seed.hwEta << std::endl;
0031 dbgCout() << " part phi, seed phi: " << part.hwPhi << ", " << seed.hwPhi << std::endl;
0032 dbgCout() << " pt, deta, dphi, r2, cone2, lt: " << part.hwPt << ", " << deta << ", " << dphi << ", "
0033 << deta * deta + dphi * dphi << ", " << rCone2_ << ", " << ret << std::endl;
0034 }
0035 return ret;
0036 }
0037
0038 std::vector<L1SCJetEmu::Particle> L1SCJetEmu::sortConstituents(const std::vector<Particle>& parts,
0039 const Particle seed) const {
0040 std::vector<Particle> sortedParts = parts;
0041 std::sort(sortedParts.begin(), sortedParts.end(), [](const Particle& a, const Particle& b) {
0042 return a.hwPt > b.hwPt;
0043 });
0044 std::vector<Particle> truncated;
0045 truncated.resize(NCONSTITSFW);
0046 for (unsigned iConst = 0; iConst < NCONSTITSFW; ++iConst) {
0047 if (iConst <
0048 sortedParts.size()) {
0049 truncated[iConst].hwEta = static_cast<detaphi_t>(sortedParts.at(iConst).hwEta - seed.hwEta);
0050 truncated[iConst].hwPhi = static_cast<detaphi_t>(deltaPhi(sortedParts.at(iConst), seed));
0051 truncated[iConst].hwPt = sortedParts.at(iConst).hwPt;
0052 } else {
0053 truncated[iConst].clear();
0054 }
0055 }
0056 return truncated;
0057 }
0058
0059 L1SCJetEmu::mass2_t L1SCJetEmu::jetMass_HW(const std::vector<Particle>& parts) const {
0060
0061
0062 static std::array<eventrig_t, hwEtaPhi_steps> cosh_lut =
0063 init_trig_lut<eventrig_t, hwEtaPhi_steps>([](float x) -> eventrig_t { return std::cosh(x); });
0064 static std::array<eventrig_t, hwEtaPhi_steps> cos_lut =
0065 init_trig_lut<eventrig_t, hwEtaPhi_steps>([](float x) -> eventrig_t { return std::cos(x); });
0066 static std::array<oddtrig_t, hwEtaPhi_steps> sin_lut =
0067 init_trig_lut<oddtrig_t, hwEtaPhi_steps>([](float x) -> oddtrig_t { return std::sin(x); });
0068 static std::array<oddtrig_t, hwEtaPhi_steps> sinh_lut =
0069 init_trig_lut<oddtrig_t, hwEtaPhi_steps>([](float x) -> oddtrig_t { return std::sinh(x); });
0070
0071 std::vector<ppt_t> en;
0072 en.resize(parts.size());
0073 std::transform(parts.begin(), parts.end(), en.begin(), [](const Particle& part) {
0074 return ppt_t(part.hwPt * cosh_lut[std::abs(part.hwEta)]);
0075 });
0076 ppt_t sum_en = std::accumulate(en.begin(), en.end(), ppt_t(0));
0077
0078 std::vector<ppt_t> px;
0079 px.resize(parts.size());
0080 std::transform(parts.begin(), parts.end(), px.begin(), [](const Particle& part) {
0081 return ppt_t(part.hwPt * cos_lut[std::abs(part.hwPhi)]);
0082 });
0083 ppt_t sum_px = std::accumulate(px.begin(), px.end(), ppt_t(0));
0084
0085 std::vector<npt_t> py;
0086 py.resize(parts.size());
0087 std::transform(parts.begin(), parts.end(), py.begin(), [](const Particle& part) {
0088 return npt_t(part.hwPt * sin_lut[std::abs(part.hwPhi)] * ((part.hwPhi >= 0) ? 1 : -1));
0089 });
0090 npt_t sum_py = std::accumulate(py.begin(), py.end(), npt_t(0));
0091
0092 std::vector<npt_t> pz;
0093 pz.resize(parts.size());
0094 std::transform(parts.begin(), parts.end(), pz.begin(), [](const Particle& part) {
0095 return npt_t(part.hwPt * sinh_lut[std::abs(part.hwEta)] * ((part.hwEta >= 0) ? 1 : -1));
0096 });
0097 npt_t sum_pz = std::accumulate(pz.begin(), pz.end(), npt_t(0));
0098
0099 return (sum_en * sum_en) - (sum_px * sum_px) - (sum_py * sum_py) - (sum_pz * sum_pz);
0100 }
0101
0102 L1SCJetEmu::Jet L1SCJetEmu::makeJet_HW(const std::vector<Particle>& parts, const Particle seed) const {
0103
0104
0105
0106 auto sumpt = [](pt_t(a), const Particle& b) { return a + b.hwPt; };
0107
0108
0109 pt_t pt = std::accumulate(parts.begin(), parts.end(), pt_t(0), sumpt);
0110 inv_pt_t inv_pt = invert_with_shift<pt_t, inv_pt_t, N_table_inv_pt>(pt, inv_pt_table_, false);
0111
0112
0113 std::vector<pt_etaphi_t> pt_deta;
0114 pt_deta.resize(parts.size());
0115 std::transform(parts.begin(), parts.end(), pt_deta.begin(), [&seed](const Particle& part) {
0116
0117 return pt_etaphi_t(part.hwPt * detaphi_t(part.hwEta - seed.hwEta));
0118 });
0119
0120 pt_etaphi_t sum_pt_eta = std::accumulate(pt_deta.begin(), pt_deta.end(), pt_etaphi_t(0));
0121 etaphi_t eta = seed.hwEta + etaphi_t(sum_pt_eta * inv_pt);
0122
0123
0124 std::vector<pt_etaphi_t> pt_dphi;
0125 pt_dphi.resize(parts.size());
0126 std::transform(parts.begin(), parts.end(), pt_dphi.begin(), [&seed](const Particle& part) {
0127
0128 return pt_etaphi_t(part.hwPt * deltaPhi(part, seed));
0129 });
0130
0131 pt_etaphi_t sum_pt_phi = std::accumulate(pt_dphi.begin(), pt_dphi.end(), pt_etaphi_t(0));
0132 etaphi_t phi = seed.hwPhi + etaphi_t(sum_pt_phi * inv_pt);
0133
0134 std::vector<Particle> truncated =
0135 sortConstituents(parts, seed);
0136 mass2_t massSq = L1SCJetEmu::jetMass_HW(truncated);
0137
0138 Jet jet;
0139 jet.hwPt = pt;
0140 jet.hwEta = eta;
0141 jet.hwPhi = phi;
0142 jet.hwMassSq = massSq;
0143 jet.constituents = parts;
0144
0145
0146 if (debug_) {
0147 std::for_each(pt_dphi.begin(), pt_dphi.end(), [](pt_etaphi_t& x) { dbgCout() << "pt_dphi: " << x << std::endl; });
0148 std::for_each(pt_deta.begin(), pt_deta.end(), [](pt_etaphi_t& x) { dbgCout() << "pt_deta: " << x << std::endl; });
0149 dbgCout() << " sum_pt_eta: " << sum_pt_eta << ", 1/pt: " << inv_pt
0150 << ", sum_pt_eta * 1/pt: " << etaphi_t(sum_pt_eta * inv_pt) << std::endl;
0151 dbgCout() << " sum_pt_phi: " << sum_pt_phi << ", 1/pt: " << inv_pt
0152 << ", sum_pt_phi * 1/pt: " << etaphi_t(sum_pt_phi * inv_pt) << std::endl;
0153 dbgCout() << " uncorr eta: " << seed.hwEta << ", phi: " << seed.hwPhi << std::endl;
0154 dbgCout() << " corr eta: " << eta << ", phi: " << phi << std::endl;
0155 dbgCout() << " pt: " << pt << std::endl;
0156 }
0157
0158 return jet;
0159 }
0160
0161 std::vector<L1SCJetEmu::Jet> L1SCJetEmu::emulateEvent(std::vector<Particle>& parts) const {
0162
0163 std::vector<Particle> work;
0164 work.resize(parts.size());
0165 std::transform(parts.begin(), parts.end(), work.begin(), [](const Particle& part) { return part; });
0166
0167 std::vector<Jet> jets;
0168 jets.reserve(nJets_);
0169 while ((!work.empty() && jets.size() < nJets_)) {
0170
0171
0172
0173
0174 Particle seed = reduce(work, op_max);
0175
0176
0177 std::vector<Particle> particlesInCone;
0178 std::copy_if(work.begin(), work.end(), std::back_inserter(particlesInCone), [&](const Particle& part) {
0179 return inCone(seed, part);
0180 });
0181 if (debug_) {
0182 dbgCout() << "Seed: " << seed.hwPt << ", " << seed.hwEta << ", " << seed.hwPhi << std::endl;
0183 dbgCout() << "N particles : " << particlesInCone.size() << std::endl;
0184 std::for_each(particlesInCone.begin(), particlesInCone.end(), [&](Particle& part) {
0185 dbgCout() << " Part: " << part.hwPt << ", " << part.hwEta << ", " << part.hwPhi << std::endl;
0186 inCone(seed, part);
0187 });
0188 }
0189 jets.push_back(makeJet_HW(particlesInCone, seed));
0190
0191 work.erase(std::remove_if(work.begin(),
0192 work.end(),
0193 [&](const Particle& part) {
0194 return inCone(seed, part);
0195 }),
0196 work.end());
0197 }
0198 return jets;
0199 }