Skip to content

Commit

Permalink
Merge pull request cms-sw#94 from thomreis/l1phase2-l2ct-eg-puppi-iso…
Browse files Browse the repository at this point in the history
…-integration-p2l1pfp-1230pre4

Add PUPPI isolation to CT L2 EG emulator
  • Loading branch information
gpetruc authored Sep 29, 2022
2 parents 1eb70ca + 467514f commit 4ef7766
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 6 deletions.
11 changes: 7 additions & 4 deletions DataFormats/L1TParticleFlow/interface/layer1_emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
63 changes: 63 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h
#define L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h

#include <list>
#include <string>
#include <vector>
#include <memory>

#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"

namespace l1ct {

struct L1EGPuppiIsoAlgoConfig {
enum { kPFIso, kPuppiIso };

int pfIsoType_;
pt_t ptMin_;
ap_int<z0_t::width + 1> 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<EGIsoObjEmu> EGIsoObjsEmu;
typedef std::vector<EGIsoEleObjEmu> EGIsoEleObjsEmu;
typedef std::vector<PuppiObj> 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<const PuppiObj*>& workPFCands, z0_t z0 = 0) const;

const L1EGPuppiIsoAlgoConfig config_;
};

} // namespace l1ct
#endif
30 changes: 28 additions & 2 deletions L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -12,9 +13,8 @@

#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/interface/egamma/L1EGPuppiIsoAlgo.h"

#include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h"
#include "L1Trigger/DemonstratorTools/interface/utilities.h"
Expand Down Expand Up @@ -54,6 +54,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 T>
class PFInstanceInputs {
Expand Down Expand Up @@ -194,6 +195,9 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> {
std::string tkEleInstanceLabel_;
l1ct::L2EgSorterEmulator l2egsorter;
l1ct::L2EgEncoderEmulator l2encoder;
edm::EDGetTokenT<std::vector<l1t::PFCandidate>> pfObjsToken_;
l1ct::L1EGPuppiIsoAlgo l2EgPuppiIsoAlgo_;
l1ct::L1EGPuppiIsoAlgo l2ElePuppiIsoAlgo_;
bool doInPtrn_;
bool doOutPtrn_;
std::unique_ptr<PatternWriter> inPtrnWrt_;
Expand All @@ -209,6 +213,9 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf)
tkEleInstanceLabel_(conf.getParameter<std::string>("tkEleInstanceLabel")),
l2egsorter(conf.getParameter<edm::ParameterSet>("sorter")),
l2encoder(conf.getParameter<edm::ParameterSet>("encoder")),
pfObjsToken_(consumes<std::vector<l1t::PFCandidate>>(conf.getParameter<edm::InputTag>("l1PFObjects"))),
l2EgPuppiIsoAlgo_(conf.getParameter<edm::ParameterSet>("puppiIsoParametersTkEm")),
l2ElePuppiIsoAlgo_(conf.getParameter<edm::ParameterSet>("puppiIsoParametersTkEle")),
doInPtrn_(conf.getParameter<bool>("writeInPattern")),
doOutPtrn_(conf.getParameter<bool>("writeOutPattern")),
inPtrnWrt_(nullptr),
Expand Down Expand Up @@ -300,6 +307,13 @@ void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::Ev
std::vector<EGIsoEleObjEmu> 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));
Expand Down Expand Up @@ -335,6 +349,7 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele,
// 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);
Expand All @@ -356,12 +371,21 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem,
// 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()));
// 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)!
Expand All @@ -376,6 +400,7 @@ 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.setEgBinaryWord(gteg.pack());
return tkem;
}
Expand All @@ -394,6 +419,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;
}
Expand Down
20 changes: 20 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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"),
Expand All @@ -49,6 +52,22 @@
nTKELE_OUT=cms.uint32(12),
nTKPHO_OUT=cms.uint32(12),
),
puppiIsoParametersTkEm = cms.PSet(
pfIsoType = cms.string("PUPPI"),
pfPtMin = cms.double(1.),
dZ = cms.double(0.6),
dRMin = cms.double(0.07),
dRMax = cms.double(0.3),
pfCandReuse = cms.bool(True)
),
puppiIsoParametersTkEle = cms.PSet(
pfIsoType = cms.string("PUPPI"),
pfPtMin = cms.double(1.),
dZ = 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(
Expand Down Expand Up @@ -133,5 +152,6 @@


l1ctLayer2EGTask = cms.Task(
l1ctLayer2Deregionizer,
l1ctLayer2EG
)
132 changes: 132 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h"

using namespace l1ct;

L1EGPuppiIsoAlgo::L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet)
: config_(pSet.getParameter<std::string>("pfIsoType"),
pSet.getParameter<double>("pfPtMin"),
pSet.getParameter<double>("dZ"),
pSet.getParameter<double>("dRMin"),
pSet.getParameter<double>("dRMax"),
pSet.getParameter<bool>("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 and the the module is configured to to so
std::list<const PuppiObj*> workPFCands;
std::list<const PuppiObj*> workPFCandsPV;
for (const auto& l1PFCand : l1PFCands) {
workPFCands.emplace_back(&l1PFCand);
workPFCandsPV.emplace_back(&l1PFCand);
}

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 and the the module is configured to to so
std::list<const PuppiObj*> workPFCands;
std::list<const PuppiObj*> workPFCandsPV;
for (const auto& l1PFCand : l1PFCands) {
workPFCands.emplace_back(&l1PFCand);
workPFCandsPV.emplace_back(&l1PFCand);
}

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 and the the module is configured to to so
std::list<const PuppiObj*> workPFCands;
for (const auto& l1PFCand : l1PFCands) {
workPFCands.emplace_back(&l1PFCand);
}

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<const PuppiObj*>& 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<z0_t::width + 1> 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 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);
continue;
}
}
}
++pfIt;
}

return sumPt;
}

0 comments on commit 4ef7766

Please sign in to comment.