From 17b58c9836ee49a01ec087f8422d85ed8f58d8fa Mon Sep 17 00:00:00 2001 From: Thomas Reis Date: Fri, 30 Apr 2021 10:35:07 +0200 Subject: [PATCH 1/5] Integrate PUPPI isolation into Layer 2 CT emulation. --- .../interface/layer1_emulator.h | 11 +- .../plugins/L1TCtL2EgProducer.cc | 55 +++++-- .../python/l1ctLayer2EG_cff.py | 20 +++ .../newfirmware/egamma/L1EGPuppiIsoAlgo.cc | 138 ++++++++++++++++++ .../src/newfirmware/egamma/L1EGPuppiIsoAlgo.h | 71 +++++++++ 5 files changed, 278 insertions(+), 17 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h index 0fcaa3580f7af..a257ed2efbda6 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -175,18 +175,20 @@ namespace l1ct { hwIsoVars[1] = 0; hwIsoVars[2] = 0; hwIsoVars[3] = 0; + hwIsoVars[4] = 0; + hwIsoVars[5] = 0; } using EGIsoObj::floatIso; - enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3 }; + enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3, PuppiIso = 4, PuppiIsoPV = 5 }; float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); } float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); } float hwIsoVar(IsoType type) const { return hwIsoVars[type]; } void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; } - iso_t hwIsoVars[4]; + iso_t hwIsoVars[6]; }; struct EGIsoEleObjEmu : public EGIsoEleObj { @@ -207,18 +209,19 @@ namespace l1ct { void clearIsoVars() { hwIsoVars[0] = 0; hwIsoVars[1] = 0; + hwIsoVars[2] = 0; } using EGIsoEleObj::floatIso; - enum IsoType { TkIso = 0, PfIso = 1 }; + enum IsoType { TkIso = 0, PfIso = 1, PuppiIso = 2 }; float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); } float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); } float hwIsoVar(IsoType type) const { return hwIsoVars[type]; } void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; } - iso_t hwIsoVars[2]; + iso_t hwIsoVars[3]; }; struct PVObjEmu : public PVObj { diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index 75265d23765a0..0ba67f6989547 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -3,6 +3,7 @@ #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" #include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/global/EDProducer.h" @@ -10,11 +11,13 @@ #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/transform.h" -#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h" -//#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.cpp" -#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h" -//#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.cpp" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/dataformats/layer1_emulator.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.cpp" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.cpp" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc" #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" #include "L1Trigger/DemonstratorTools/interface/utilities.h" @@ -54,6 +57,7 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { void convertToEmu(const l1t::TkElectron &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; void convertToEmu(const l1t::TkEm &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; + void convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const; template class PFInstanceInputs { @@ -194,6 +198,9 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { std::string tkEleInstanceLabel_; l1ct::L2EgSorterEmulator l2egsorter; l1ct::L2EgEncoderEmulator l2encoder; + edm::EDGetTokenT> pfObjsToken_; + l1ct::L1EGPuppiIsoAlgo l2EgPuppiIsoAlgo_; + l1ct::L1EGPuppiIsoAlgo l2ElePuppiIsoAlgo_; bool doInPtrn_; bool doOutPtrn_; std::unique_ptr inPtrnWrt_; @@ -209,6 +216,9 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) tkEleInstanceLabel_(conf.getParameter("tkEleInstanceLabel")), l2egsorter(conf.getParameter("sorter")), l2encoder(conf.getParameter("encoder")), + pfObjsToken_(consumes>(conf.getParameter("l1PFObjects"))), + l2EgPuppiIsoAlgo_(conf.getParameter("egPFIso")), + l2ElePuppiIsoAlgo_(conf.getParameter("elePFIso")), doInPtrn_(conf.getParameter("writeInPattern")), doOutPtrn_(conf.getParameter("writeOutPattern")), inPtrnWrt_(nullptr), @@ -300,6 +310,13 @@ void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::Ev std::vector out_eles_emu; l2egsorter.run(*boards, out_photons_emu, out_eles_emu); + // PUPPI isolation + auto &pfObjs = iEvent.get(pfObjsToken_); + l1ct::PuppiObjs puppiObjs; + convertToPuppi(pfObjs, puppiObjs); + l2EgPuppiIsoAlgo_.run(out_photons_emu, puppiObjs); + l2ElePuppiIsoAlgo_.run(out_eles_emu, puppiObjs); + if (doOutPtrn_) { l1t::demo::EventData outData; outData.add({"eglayer2", 0}, l2encoder.encodeLayer2EgObjs(out_photons_emu, out_eles_emu)); @@ -332,9 +349,9 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele, } refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, tkele.trkPtr())); emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; - // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso - emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol() * tkele.pt())); - emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol() * tkele.pt())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkele.puppiIsol())); // std::cout << "[convertToEmu] TkEle pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egelectron.push_back(emu); @@ -353,15 +370,24 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem, } refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, edm::Ptr(nullptr, 0))); emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; - // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso - emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol() * tkem.pt())); - emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol() * tkem.pt())); - emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV() * tkem.pt())); - emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol())); + emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol())); + emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol())); + emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV())); + emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV())); + emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, l1ct::Scales::makeIso(tkem.puppiIsolPV())); // std::cout << "[convertToEmu] TkEM pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egphoton.push_back(emu); } +void L1TCtL2EgProducer::convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const { + for (const auto &l1PFCand : l1PFCands) { + l1ct::PuppiObj obj; + obj.initFromBits(l1PFCand.encodedPuppi64()); + puppiObjs.emplace_back(obj); + } +} + l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso, const RefRemapper &refRemapper) const { // std::cout << "[convertFromEmu] TkEm pt: " << egiso.hwPt << " eta: " << egiso.hwEta << " phi: " << egiso.hwPhi << " staidx: " << egiso.sta_idx << std::endl; // NOTE: the TkEM object is created with the accuracy as in GT object (not the Correlator internal one)! @@ -376,6 +402,8 @@ l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso, cons tkem.setHwQual(gteg.quality); tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso)); tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV)); + tkem.setPuppiIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIso)); + tkem.setPuppiIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIsoPV)); tkem.setEgBinaryWord(gteg.pack()); return tkem; } @@ -394,6 +422,7 @@ l1t::TkElectron L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoEleObjEmu &eg egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso)); tkele.setHwQual(gteg.quality); tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso)); + tkele.setPuppiIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PuppiIso)); tkele.setEgBinaryWord(gteg.pack()); return tkele; } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index af063d32cce49..a0b07430faaaa 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -1,5 +1,7 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.Phase2L1ParticleFlow.DeregionizerProducer_cfi import DeregionizerProducer as l1ctLayer2Deregionizer + l1ctLayer2EG = cms.EDProducer( "L1TCtL2EgProducer", tkElectrons=cms.VPSet( @@ -36,6 +38,7 @@ channels=cms.vint32(-1) ), ), + l1PFObjects = cms.InputTag("l1ctLayer2Deregionizer", "Puppi"), egStaInstanceLabel=cms.string("L1CtEgEE"), tkEmInstanceLabel=cms.string("L1CtTkEm"), tkEleInstanceLabel=cms.string("L1CtTkElectron"), @@ -49,6 +52,22 @@ nTKELE_OUT=cms.uint32(12), nTKPHO_OUT=cms.uint32(12), ), + egPFIso = cms.PSet( + pfIsoType = cms.string("PUPPI"), + pfPtMin = cms.double(1.), + dZMax = cms.double(0.6), + dRMin = cms.double(0.07), + dRMax = cms.double(0.3), + pfCandReuse = cms.bool(True) + ), + elePFIso = cms.PSet( + pfIsoType = cms.string("PUPPI"), + pfPtMin = cms.double(1.), + dZMax = cms.double(0.6), + dRMin = cms.double(0.03), + dRMax = cms.double(0.2), + pfCandReuse = cms.bool(True) + ), writeInPattern=cms.bool(False), writeOutPattern=cms.bool(False), inPatternFile=cms.PSet( @@ -133,5 +152,6 @@ l1ctLayer2EGTask = cms.Task( + l1ctLayer2Deregionizer, l1ctLayer2EG ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc new file mode 100644 index 0000000000000..ae0d11bcb1f00 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc @@ -0,0 +1,138 @@ +#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h" + +using namespace l1ct; + +L1EGPuppiIsoAlgo::L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet) + : config_(pSet.getParameter("pfIsoType"), + pSet.getParameter("pfPtMin"), + pSet.getParameter("dZMax"), + pSet.getParameter("dRMin"), + pSet.getParameter("dRMax"), + pSet.getParameter("pfCandReuse")) {} + +void L1EGPuppiIsoAlgo::run(const EGIsoObjsEmu& l1EGs, + const PuppiObjs& l1PFCands, + EGIsoObjsEmu& outL1EGs, + z0_t z0) const { + outL1EGs.reserve(l1EGs.size()); + + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used + std::list> workPFCands; + std::list> workPFCandsPV; + for (unsigned i = 0; i < l1PFCands.size(); ++i) { + workPFCands.emplace_back(std::make_shared(l1PFCands[i])); + workPFCandsPV.emplace_back(std::make_shared(l1PFCands[i])); + } + + for (const auto& l1EG : l1EGs) { + auto outL1EG(l1EG); + iso_t iso = 0; + iso_t isoPV = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1EG, workPFCands); + isoPV = calcIso(l1EG, workPFCandsPV, z0); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PfIso, iso); + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, isoPV); + } else { + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, iso); + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, isoPV); + } + outL1EGs.emplace_back(outL1EG); + } +} + +void L1EGPuppiIsoAlgo::run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t z0) const { + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used + std::list> workPFCands; + std::list> workPFCandsPV; + for (unsigned i = 0; i < l1PFCands.size(); ++i) { + workPFCands.emplace_back(std::make_shared(l1PFCands[i])); + workPFCandsPV.emplace_back(std::make_shared(l1PFCands[i])); + } + + for (auto& l1EG : l1EGs) { + iso_t iso = 0; + iso_t isoPV = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1EG, workPFCands); + isoPV = calcIso(l1EG, workPFCandsPV, z0); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + l1EG.setHwIso(EGIsoObjEmu::IsoType::PfIso, iso); + l1EG.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, isoPV); + } else { + l1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, iso); + l1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, isoPV); + } + } +} + +void L1EGPuppiIsoAlgo::run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const { + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used + std::list> workPFCands; + for (unsigned i = 0; i < l1PFCands.size(); ++i) { + workPFCands.emplace_back(std::make_shared(l1PFCands[i])); + } + + for (auto& l1Ele : l1Eles) { + iso_t iso = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1Ele, workPFCands); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + l1Ele.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, iso); + } else { + l1Ele.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, iso); + } + } +} + +iso_t L1EGPuppiIsoAlgo::calcIso(const EGIsoObj& l1EG, + std::list>& workPFCands, + z0_t z0) const { + iso_t sumPt = 0; + + auto pfIt = workPFCands.cbegin(); + while (pfIt != workPFCands.cend()) { + // use the PF candidate pT if it is within the cone and optional dz cut for charged PF candidates + const auto workPFCand = *pfIt; + z0_t pfCandZ0 = 0; + if (workPFCand->hwId.charged()) { + pfCandZ0 = workPFCand->hwZ0(); + } + + // calculate dz + ap_int dz = z0 - pfCandZ0; + if (dz < 0) { + dz = -dz; + } + + if (workPFCand->intCharge() == 0 || (workPFCand->intCharge() != 0 && dz < config_.dZMax_)) { + const auto dR2 = dr2_int(l1EG.hwEta, l1EG.hwPhi, workPFCand->hwEta, workPFCand->hwPhi); + if (dR2 >= config_.dRMin2_ && dR2 < config_.dRMax2_ && workPFCand->hwPt >= config_.ptMin_) { + sumPt += workPFCand->hwPt; + // remove the candidate from the collection if noReuse is true + if (!config_.pfCandReuse_) { + // this returns an iterator to the next element already so no need to increase here + pfIt = workPFCands.erase(pfIt); + } else { + ++pfIt; + } + } else { + ++pfIt; + } + } else { + ++pfIt; + } + } + + return sumPt; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h b/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h new file mode 100644 index 0000000000000..03dc07bbfbafa --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h @@ -0,0 +1,71 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h +#define L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h + +#include +#include +#include +#include + +#include "DataFormats/Math/interface/deltaR.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#ifdef CMSSW_GIT_HASH +#include "../dataformats/datatypes.h" +#include "../dataformats/layer1_emulator.h" +#include "../dataformats/egamma.h" +#include "../dataformats/puppi.h" +#else +#include "../../../dataformats/datatypes.h" +#include "../../../dataformats/layer1_emulator.h" +#include "../../../dataformats/egamma.h" +#include "../../../dataformats/puppi.h" +#endif + +namespace l1ct { + + struct L1EGPuppiIsoAlgoConfig { + enum { kPFIso, kPuppiIso }; + + int pfIsoType_; + pt_t ptMin_; + ap_int dZMax_; + int dRMin2_; + int dRMax2_; + bool pfCandReuse_; + + L1EGPuppiIsoAlgoConfig(const std::string& pfIsoTypeStr, + const float ptMin, + const float dZMax, + const float dRMin, + const float dRMax, + const bool pfCandReuse) + : pfIsoType_(pfIsoTypeStr == "PF" ? kPFIso : kPuppiIso), + ptMin_(Scales::makePtFromFloat(ptMin)), + dZMax_(Scales::makeZ0(dZMax)), + dRMin2_(Scales::makeDR2FromFloatDR(dRMin)), + dRMax2_(Scales::makeDR2FromFloatDR(dRMax)), + pfCandReuse_(pfCandReuse) {} + }; + + typedef std::vector EGIsoObjsEmu; + typedef std::vector EGIsoEleObjsEmu; + typedef std::vector PuppiObjs; + + class L1EGPuppiIsoAlgo { + public: + L1EGPuppiIsoAlgo(const L1EGPuppiIsoAlgoConfig& config) : config_(config) {} + L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet); + virtual ~L1EGPuppiIsoAlgo() = default; + + void run(const EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, EGIsoObjsEmu& outL1EGs, z0_t z0 = 0) const; + void run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t z0 = 0) const; + void run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const; + + private: + iso_t calcIso(const EGIsoObj& l1EG, std::list>& workPFCands, z0_t z0 = 0) const; + + const L1EGPuppiIsoAlgoConfig config_; + }; + +} // namespace l1ct +#endif From 2ce000d98b5232ed038401678fe179cf17d8eea6 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 20 May 2022 15:45:44 +0200 Subject: [PATCH 2/5] Fix conversion of Isolation variables from emulator to CMSSW objects --- .../plugins/L1TCtL2EgProducer.cc | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index 0ba67f6989547..571d73c525efd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -349,9 +349,10 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele, } refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, tkele.trkPtr())); emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; - emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol())); - emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol())); - emu.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkele.puppiIsol())); + // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso + emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol() * tkele.pt())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol() * tkele.pt())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkele.puppiIsol() * tkele.pt())); // std::cout << "[convertToEmu] TkEle pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egelectron.push_back(emu); @@ -370,12 +371,13 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem, } refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, edm::Ptr(nullptr, 0))); emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; - emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol())); - emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol())); - emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol())); - emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV())); - emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV())); - emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, l1ct::Scales::makeIso(tkem.puppiIsolPV())); + // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso + emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, l1ct::Scales::makeIso(tkem.puppiIsolPV() * tkem.pt())); // std::cout << "[convertToEmu] TkEM pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egphoton.push_back(emu); } From 27c90004764d701aedc6bd7c7e35e0f6a50625c2 Mon Sep 17 00:00:00 2001 From: Thomas Reis Date: Tue, 16 Aug 2022 15:26:06 +0200 Subject: [PATCH 3/5] Fix conflicts. --- .../egamma/L1EGPuppiIsoAlgo.h | 16 ++++------------ .../plugins/L1TCtL2EgProducer.cc | 11 ++++------- .../{newfirmware => }/egamma/L1EGPuppiIsoAlgo.cc | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) rename L1Trigger/Phase2L1ParticleFlow/{src/newfirmware => interface}/egamma/L1EGPuppiIsoAlgo.h (84%) rename L1Trigger/Phase2L1ParticleFlow/src/{newfirmware => }/egamma/L1EGPuppiIsoAlgo.cc (98%) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h similarity index 84% rename from L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h rename to L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h index 03dc07bbfbafa..55e0fea1aced4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h @@ -7,20 +7,12 @@ #include #include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/puppi.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" -#ifdef CMSSW_GIT_HASH -#include "../dataformats/datatypes.h" -#include "../dataformats/layer1_emulator.h" -#include "../dataformats/egamma.h" -#include "../dataformats/puppi.h" -#else -#include "../../../dataformats/datatypes.h" -#include "../../../dataformats/layer1_emulator.h" -#include "../../../dataformats/egamma.h" -#include "../../../dataformats/puppi.h" -#endif - namespace l1ct { struct L1EGPuppiIsoAlgoConfig { diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index 571d73c525efd..a6ffbf25ef209 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -11,13 +11,10 @@ #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/transform.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/dataformats/layer1_emulator.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.cpp" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.cpp" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc" +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h" #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" #include "L1Trigger/DemonstratorTools/interface/utilities.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc similarity index 98% rename from L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc rename to L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc index ae0d11bcb1f00..c07c0ad4e07db 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc @@ -1,4 +1,4 @@ -#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/L1EGPuppiIsoAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h" using namespace l1ct; From ccc435bd4208a5d8048930b3f9b7b985021d390a Mon Sep 17 00:00:00 2001 From: Thomas Reis Date: Fri, 23 Sep 2022 19:22:30 +0200 Subject: [PATCH 4/5] Implement reviewer comments. --- .../Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc | 6 ++---- L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py | 8 ++++---- .../Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index a6ffbf25ef209..99b0251eff85b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -214,8 +214,8 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) l2egsorter(conf.getParameter("sorter")), l2encoder(conf.getParameter("encoder")), pfObjsToken_(consumes>(conf.getParameter("l1PFObjects"))), - l2EgPuppiIsoAlgo_(conf.getParameter("egPFIso")), - l2ElePuppiIsoAlgo_(conf.getParameter("elePFIso")), + l2EgPuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEm")), + l2ElePuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEle")), doInPtrn_(conf.getParameter("writeInPattern")), doOutPtrn_(conf.getParameter("writeOutPattern")), inPtrnWrt_(nullptr), @@ -374,7 +374,6 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem, emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol() * tkem.pt())); emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV() * tkem.pt())); emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV() * tkem.pt())); - emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, l1ct::Scales::makeIso(tkem.puppiIsolPV() * tkem.pt())); // std::cout << "[convertToEmu] TkEM pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egphoton.push_back(emu); } @@ -402,7 +401,6 @@ l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso, cons tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso)); tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV)); tkem.setPuppiIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIso)); - tkem.setPuppiIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIsoPV)); tkem.setEgBinaryWord(gteg.pack()); return tkem; } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index a0b07430faaaa..80c341d5cc227 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -52,18 +52,18 @@ nTKELE_OUT=cms.uint32(12), nTKPHO_OUT=cms.uint32(12), ), - egPFIso = cms.PSet( + puppiIsoParametersTkEm = cms.PSet( pfIsoType = cms.string("PUPPI"), pfPtMin = cms.double(1.), - dZMax = cms.double(0.6), + dZ = cms.double(0.6), dRMin = cms.double(0.07), dRMax = cms.double(0.3), pfCandReuse = cms.bool(True) ), - elePFIso = cms.PSet( + puppiIsoParametersTkEle = cms.PSet( pfIsoType = cms.string("PUPPI"), pfPtMin = cms.double(1.), - dZMax = cms.double(0.6), + dZ = cms.double(0.6), dRMin = cms.double(0.03), dRMax = cms.double(0.2), pfCandReuse = cms.bool(True) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc index c07c0ad4e07db..b3b0fead63234 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc @@ -5,7 +5,7 @@ using namespace l1ct; L1EGPuppiIsoAlgo::L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet) : config_(pSet.getParameter("pfIsoType"), pSet.getParameter("pfPtMin"), - pSet.getParameter("dZMax"), + pSet.getParameter("dZ"), pSet.getParameter("dRMin"), pSet.getParameter("dRMax"), pSet.getParameter("pfCandReuse")) {} From 467514f535f9729b52aed63e4b827afbb61a48a6 Mon Sep 17 00:00:00 2001 From: Thomas Reis Date: Mon, 26 Sep 2022 17:57:21 +0200 Subject: [PATCH 5/5] Replace shared pointer with bare cosnt pointer in list of pointers to candidates. --- .../interface/egamma/L1EGPuppiIsoAlgo.h | 2 +- .../src/egamma/L1EGPuppiIsoAlgo.cc | 46 ++++++++----------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h index 55e0fea1aced4..a7a87bba35262 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h @@ -54,7 +54,7 @@ namespace l1ct { void run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const; private: - iso_t calcIso(const EGIsoObj& l1EG, std::list>& workPFCands, z0_t z0 = 0) const; + iso_t calcIso(const EGIsoObj& l1EG, std::list& workPFCands, z0_t z0 = 0) const; const L1EGPuppiIsoAlgoConfig config_; }; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc index b3b0fead63234..4d77d7866c0c0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc @@ -17,12 +17,12 @@ void L1EGPuppiIsoAlgo::run(const EGIsoObjsEmu& l1EGs, outL1EGs.reserve(l1EGs.size()); // make a list of pointers to PF candidates - // the pointer will be removed from the list once the candidate has been used - std::list> workPFCands; - std::list> workPFCandsPV; - for (unsigned i = 0; i < l1PFCands.size(); ++i) { - workPFCands.emplace_back(std::make_shared(l1PFCands[i])); - workPFCandsPV.emplace_back(std::make_shared(l1PFCands[i])); + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + std::list workPFCandsPV; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); + workPFCandsPV.emplace_back(&l1PFCand); } for (const auto& l1EG : l1EGs) { @@ -47,12 +47,12 @@ void L1EGPuppiIsoAlgo::run(const EGIsoObjsEmu& l1EGs, void L1EGPuppiIsoAlgo::run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t z0) const { // make a list of pointers to PF candidates - // the pointer will be removed from the list once the candidate has been used - std::list> workPFCands; - std::list> workPFCandsPV; - for (unsigned i = 0; i < l1PFCands.size(); ++i) { - workPFCands.emplace_back(std::make_shared(l1PFCands[i])); - workPFCandsPV.emplace_back(std::make_shared(l1PFCands[i])); + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + std::list workPFCandsPV; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); + workPFCandsPV.emplace_back(&l1PFCand); } for (auto& l1EG : l1EGs) { @@ -75,10 +75,10 @@ void L1EGPuppiIsoAlgo::run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t void L1EGPuppiIsoAlgo::run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const { // make a list of pointers to PF candidates - // the pointer will be removed from the list once the candidate has been used - std::list> workPFCands; - for (unsigned i = 0; i < l1PFCands.size(); ++i) { - workPFCands.emplace_back(std::make_shared(l1PFCands[i])); + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); } for (auto& l1Ele : l1Eles) { @@ -95,9 +95,7 @@ void L1EGPuppiIsoAlgo::run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) } } -iso_t L1EGPuppiIsoAlgo::calcIso(const EGIsoObj& l1EG, - std::list>& workPFCands, - z0_t z0) const { +iso_t L1EGPuppiIsoAlgo::calcIso(const EGIsoObj& l1EG, std::list& workPFCands, z0_t z0) const { iso_t sumPt = 0; auto pfIt = workPFCands.cbegin(); @@ -119,19 +117,15 @@ iso_t L1EGPuppiIsoAlgo::calcIso(const EGIsoObj& l1EG, const auto dR2 = dr2_int(l1EG.hwEta, l1EG.hwPhi, workPFCand->hwEta, workPFCand->hwPhi); if (dR2 >= config_.dRMin2_ && dR2 < config_.dRMax2_ && workPFCand->hwPt >= config_.ptMin_) { sumPt += workPFCand->hwPt; - // remove the candidate from the collection if noReuse is true + // remove the candidate from the collection if the module is configured to not reuse them if (!config_.pfCandReuse_) { // this returns an iterator to the next element already so no need to increase here pfIt = workPFCands.erase(pfIt); - } else { - ++pfIt; + continue; } - } else { - ++pfIt; } - } else { - ++pfIt; } + ++pfIt; } return sumPt;