File indexing completed on 2025-05-09 22:40:11
0001
0002 #include <vector>
0003 #include <numeric>
0004 #include <string>
0005
0006
0007
0008 #include "FWCore/Framework/interface/global/EDProducer.h"
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Utilities/interface/InputTag.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013
0014 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0015 #include "DataFormats/L1TParticleFlow/interface/PFJet.h"
0016 #include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h"
0017 #include "DataFormats/Math/interface/deltaR.h"
0018
0019
0020 #include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h"
0021 #include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h"
0022
0023 class L1SeedConePFJetProducer : public edm::global::EDProducer<> {
0024 public:
0025 explicit L1SeedConePFJetProducer(const edm::ParameterSet&);
0026 ~L1SeedConePFJetProducer() override;
0027 static void fillDescriptions(edm::ConfigurationDescriptions& description);
0028
0029 private:
0030
0031
0032 void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
0033
0034
0035 const float coneSize;
0036 const bool wideConeJet;
0037 const unsigned nJets;
0038 const bool HW;
0039 const bool debug;
0040 const bool doCorrections;
0041 L1SCJetEmu emulator;
0042 edm::EDGetTokenT<std::vector<l1t::PFCandidate>> l1PFToken;
0043 l1tpf::corrector corrector;
0044
0045 std::vector<l1t::PFJet> processEvent_SW(std::vector<edm::Ptr<l1t::PFCandidate>>& parts) const;
0046 std::vector<l1t::PFJet> processEvent_HW(std::vector<edm::Ptr<l1t::PFCandidate>>& parts) const;
0047
0048 l1t::PFJet makeJet_SW(const std::vector<edm::Ptr<l1t::PFCandidate>>& parts,
0049 const edm::Ptr<l1t::PFCandidate>& seed) const;
0050
0051 std::pair<std::vector<L1SCJetEmu::Particle>, std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>>>
0052 convertEDMToHW(std::vector<edm::Ptr<l1t::PFCandidate>>& edmParticles) const;
0053
0054 std::vector<l1t::PFJet> convertHWToEDM(
0055 std::vector<L1SCJetEmu::Jet> hwJets,
0056 std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>> constituentMap) const;
0057 };
0058
0059 L1SeedConePFJetProducer::L1SeedConePFJetProducer(const edm::ParameterSet& cfg)
0060 : coneSize(cfg.getParameter<double>("coneSize")),
0061 wideConeJet(cfg.getParameter<bool>("wideConeJet")),
0062 nJets(cfg.getParameter<unsigned>("nJets")),
0063 HW(cfg.getParameter<bool>("HW")),
0064 debug(cfg.getParameter<bool>("debug")),
0065 doCorrections(cfg.getParameter<bool>("doCorrections")),
0066 emulator(L1SCJetEmu(debug, coneSize, nJets)),
0067 l1PFToken(consumes<std::vector<l1t::PFCandidate>>(cfg.getParameter<edm::InputTag>("L1PFObjects"))) {
0068 produces<l1t::PFJetCollection>();
0069 if (doCorrections) {
0070 corrector = l1tpf::corrector(
0071 cfg.getParameter<std::string>("correctorFile"), cfg.getParameter<std::string>("correctorDir"), -1., debug, HW);
0072 }
0073 }
0074
0075 void L1SeedConePFJetProducer::produce(edm::StreamID ,
0076 edm::Event& iEvent,
0077 const edm::EventSetup& iSetup) const {
0078 std::unique_ptr<l1t::PFJetCollection> newPFJetCollection(new l1t::PFJetCollection);
0079
0080 edm::Handle<l1t::PFCandidateCollection> l1PFCandidates;
0081 iEvent.getByToken(l1PFToken, l1PFCandidates);
0082 std::vector<edm::Ptr<l1t::PFCandidate>> particles;
0083 for (unsigned i = 0; i < (*l1PFCandidates).size(); i++) {
0084 particles.push_back(edm::Ptr<l1t::PFCandidate>(l1PFCandidates, i));
0085 }
0086
0087 std::vector<l1t::PFJet> jets;
0088 if (HW) {
0089 jets = processEvent_HW(particles);
0090 } else {
0091 jets = processEvent_SW(particles);
0092 }
0093 std::sort(jets.begin(), jets.end(), [](l1t::PFJet i, l1t::PFJet j) { return (i.pt() > j.pt()); });
0094 newPFJetCollection->swap(jets);
0095 iEvent.put(std::move(newPFJetCollection));
0096 }
0097
0098
0099
0100 L1SeedConePFJetProducer::~L1SeedConePFJetProducer() {}
0101
0102 l1t::PFJet L1SeedConePFJetProducer::makeJet_SW(const std::vector<edm::Ptr<l1t::PFCandidate>>& parts,
0103 const edm::Ptr<l1t::PFCandidate>& seed) const {
0104 auto sumpt = [](float a, const edm::Ptr<l1t::PFCandidate>& b) { return a + b->pt(); };
0105
0106
0107 float pt = std::accumulate(parts.begin(), parts.end(), 0., sumpt);
0108
0109
0110 std::vector<float> pt_deta;
0111 pt_deta.resize(parts.size());
0112 std::transform(parts.begin(), parts.end(), pt_deta.begin(), [&seed, &pt](const edm::Ptr<l1t::PFCandidate>& part) {
0113 return (part->pt() / pt) * (part->eta() - seed->eta());
0114 });
0115
0116 float eta = std::accumulate(pt_deta.begin() + 1, pt_deta.end(), seed->eta());
0117
0118
0119 std::vector<float> pt_dphi;
0120 pt_dphi.resize(parts.size());
0121 std::transform(parts.begin(), parts.end(), pt_dphi.begin(), [&seed, &pt](const edm::Ptr<l1t::PFCandidate>& part) {
0122 return (part->pt() / pt) * reco::deltaPhi(part->phi(), seed->phi());
0123 });
0124
0125 float phi = std::accumulate(pt_dphi.begin() + 1, pt_dphi.end(), seed->phi());
0126
0127
0128 std::vector<float> en;
0129 en.resize(parts.size());
0130 std::transform(parts.begin(), parts.end(), en.begin(), [](const edm::Ptr<l1t::PFCandidate>& part) {
0131 return std::pow(std::pow((part->pt() * std::cosh(part->eta())), 2) + std::pow(part->mass(), 2), 0.5);
0132 });
0133 float en_tot = std::accumulate(en.begin(), en.end(), 0.0);
0134
0135 auto sumpx = [](float a, const edm::Ptr<l1t::PFCandidate>& b) { return a + (b->pt() * std::cos(b->phi())); };
0136 float px_tot = std::accumulate(parts.begin(), parts.end(), 0.0, sumpx);
0137
0138 auto sumpy = [](float a, const edm::Ptr<l1t::PFCandidate>& b) { return a + (b->pt() * std::sin(b->phi())); };
0139 float py_tot = std::accumulate(parts.begin(), parts.end(), 0.0, sumpy);
0140
0141 auto sumpz = [](float a, const edm::Ptr<l1t::PFCandidate>& b) { return a + (b->pt() * std::sinh(b->eta())); };
0142 float pz_tot = std::accumulate(parts.begin(), parts.end(), 0.0, sumpz);
0143
0144 float mass = std::sqrt((en_tot * en_tot) - (px_tot * px_tot) - (py_tot * py_tot) - (pz_tot * pz_tot));
0145
0146 l1t::PFJet jet(pt, eta, phi, mass);
0147
0148 for (auto it = parts.begin(); it != parts.end(); it++) {
0149 jet.addConstituent(*it);
0150 }
0151
0152 if (doCorrections) {
0153 jet.calibratePt(corrector.correctedPt(jet.pt(), jet.eta()));
0154 }
0155
0156 return jet;
0157 }
0158
0159 std::vector<l1t::PFJet> L1SeedConePFJetProducer::processEvent_SW(std::vector<edm::Ptr<l1t::PFCandidate>>& parts) const {
0160
0161 std::stable_sort(parts.begin(), parts.end(), [](edm::Ptr<l1t::PFCandidate> i, edm::Ptr<l1t::PFCandidate> j) {
0162 return (i->pt() > j->pt());
0163 });
0164 std::vector<l1t::PFJet> jets;
0165 jets.reserve(nJets);
0166
0167 while (!parts.empty() &&
0168 jets.size() < nJets) {
0169 edm::Ptr<l1t::PFCandidate> seed =
0170 parts.at(0);
0171
0172
0173 std::vector<edm::Ptr<l1t::PFCandidate>> particlesInCone;
0174 std::copy_if(
0175 parts.begin(), parts.end(), std::back_inserter(particlesInCone), [&](const edm::Ptr<l1t::PFCandidate>& part) {
0176 return reco::deltaR<l1t::PFCandidate, l1t::PFCandidate>(*seed, *part) <= coneSize;
0177 });
0178
0179 jets.push_back(makeJet_SW(particlesInCone, seed));
0180
0181 parts.erase(std::remove_if(parts.begin(),
0182 parts.end(),
0183 [&](const edm::Ptr<l1t::PFCandidate>& part) {
0184 return reco::deltaR<l1t::PFCandidate, l1t::PFCandidate>(*seed, *part) <= coneSize;
0185 }),
0186 parts.end());
0187 }
0188
0189 return jets;
0190 }
0191
0192 std::vector<l1t::PFJet> L1SeedConePFJetProducer::processEvent_HW(std::vector<edm::Ptr<l1t::PFCandidate>>& parts) const {
0193
0194
0195 std::pair<std::vector<L1SCJetEmu::Particle>, std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>>>
0196 particles = convertEDMToHW(parts);
0197 std::vector<L1SCJetEmu::Jet> jets = emulator.emulateEvent(particles.first);
0198 return convertHWToEDM(jets, particles.second);
0199 }
0200
0201 std::pair<std::vector<L1SCJetEmu::Particle>, std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>>>
0202 L1SeedConePFJetProducer::convertEDMToHW(std::vector<edm::Ptr<l1t::PFCandidate>>& edmParticles) const {
0203 std::vector<l1ct::PuppiObjEmu> hwParticles;
0204 std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>> candidateMap;
0205 std::for_each(edmParticles.begin(), edmParticles.end(), [&](edm::Ptr<l1t::PFCandidate>& edmParticle) {
0206 l1ct::PuppiObjEmu particle;
0207 particle.initFromBits(edmParticle->encodedPuppi64());
0208 particle.srcCand = edmParticle.get();
0209 candidateMap.insert(std::make_pair(edmParticle.get(), edmParticle));
0210 hwParticles.push_back(particle);
0211 });
0212 return std::make_pair(hwParticles, candidateMap);
0213 }
0214
0215 std::vector<l1t::PFJet> L1SeedConePFJetProducer::convertHWToEDM(
0216 std::vector<L1SCJetEmu::Jet> hwJets,
0217 std::unordered_map<const l1t::PFCandidate*, edm::Ptr<l1t::PFCandidate>> constituentMap) const {
0218 std::vector<l1t::PFJet> edmJets;
0219 std::for_each(hwJets.begin(), hwJets.end(), [&](L1SCJetEmu::Jet jet) {
0220 if (doCorrections) {
0221 float correctedPt = corrector.correctedPt(jet.floatPt(), jet.floatEta());
0222 jet.hwPt = correctedPt;
0223 }
0224 l1gt::Jet gtJet = jet.toGT();
0225 l1t::PFJet edmJet(l1gt::Scales::floatPt(gtJet.v3.pt),
0226 l1gt::Scales::floatEta(gtJet.v3.eta),
0227 l1gt::Scales::floatPhi(gtJet.v3.phi),
0228 0,
0229 gtJet.v3.pt.V,
0230 gtJet.v3.eta.V,
0231 gtJet.v3.phi.V);
0232 edmJet.setEncodedJet(l1t::PFJet::HWEncoding::CT, jet.pack());
0233
0234 if (wideConeJet) {
0235 edmJet.setEncodedJet(l1t::PFJet::HWEncoding::GTWide, jet.toGTWide().pack());
0236 edmJet.setMass(std::sqrt(l1gt::Scales::floatMassSq(jet.toGTWide().hwMassSq)));
0237 } else {
0238 edmJet.setEncodedJet(l1t::PFJet::HWEncoding::GT, jet.toGT().pack());
0239 }
0240
0241
0242 std::vector<edm::Ptr<l1t::PFCandidate>> constituents;
0243 std::for_each(jet.constituents.begin(), jet.constituents.end(), [&](auto constituent) {
0244 edmJet.addConstituent(constituentMap[constituent.srcCand]);
0245 });
0246 edmJets.push_back(edmJet);
0247 });
0248 return edmJets;
0249 }
0250
0251 void L1SeedConePFJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0252 edm::ParameterSetDescription desc;
0253 desc.add<edm::InputTag>("L1PFObjects", edm::InputTag("l1tLayer1", "Puppi"));
0254 desc.add<uint32_t>("nJets", 16);
0255 desc.add<double>("coneSize", 0.4);
0256 desc.add<bool>("wideConeJet", false);
0257 desc.add<bool>("HW", false);
0258 desc.add<bool>("debug", false);
0259 desc.add<bool>("doCorrections", false);
0260 desc.add<std::string>("correctorFile", "");
0261 desc.add<std::string>("correctorDir", "");
0262 descriptions.addWithDefaultLabel(desc);
0263 }
0264
0265 DEFINE_FWK_MODULE(L1SeedConePFJetProducer);