Skip to content

Commit

Permalink
Merge pull request #67 from p2l1pfp/VourMa-deregionizer-emulator-dev
Browse files Browse the repository at this point in the history
Sync deregionizer with correlator-common repo
  • Loading branch information
gpetruc committed Aug 4, 2021
2 parents 4988dbd + be7556b commit 686d277
Show file tree
Hide file tree
Showing 10 changed files with 556 additions and 6 deletions.
16 changes: 13 additions & 3 deletions DataFormats/L1TParticleFlow/interface/RegionalOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ namespace l1t {
: src_(src), ibegin_(ibegin), iend_(iend) {}
};

RegionalOutput() : refprod_(), values_(), regions_() {}
RegionalOutput(const edm::RefProd<T>& prod) : refprod_(prod), values_(), regions_() {}
RegionalOutput() : refprod_(), values_(), regions_(), etas_(), phis_() {}
RegionalOutput(const edm::RefProd<T>& prod) : refprod_(prod), values_(), regions_(), etas_(), phis_() {}

void addRegion(const std::vector<int>& indices) {
void addRegion(const std::vector<int>& indices, const float eta, const float phi) {
regions_.emplace_back((regions_.empty() ? 0 : regions_.back()) + indices.size());
values_.insert(values_.end(), indices.begin(), indices.end());
etas_.push_back(eta);
phis_.push_back(phi);
}

edm::ProductID id() const { return refprod_.id(); }
Expand All @@ -108,16 +110,22 @@ namespace l1t {
void clear() {
values_.clear();
regions_.clear();
etas_.clear();
phis_.clear();
}
void shrink_to_fit() {
values_.shrink_to_fit();
regions_.shrink_to_fit();
etas_.shrink_to_fit();
phis_.shrink_to_fit();
}

const_iterator begin() const { return const_iterator(this, 0); }
const_iterator end() const { return const_iterator(this, values_.size()); }

Region region(unsigned int ireg) const { return Region(this, ireg == 0 ? 0 : regions_[ireg - 1], regions_[ireg]); }
const float eta(unsigned int ireg) const { return etas_[ireg]; }
const float phi(unsigned int ireg) const { return phis_[ireg]; }

ref refAt(unsigned int idx) const { return ref(refprod_, values_[idx]); }
const value_type& objAt(unsigned int idx) const { return (*refprod_)[values_[idx]]; }
Expand All @@ -129,6 +137,8 @@ namespace l1t {
refprod refprod_;
std::vector<unsigned int> values_; // list of indices to objects in each region, flattened.
std::vector<unsigned int> regions_; // for each region, store the index of one-past the last object in values
std::vector<float> etas_; // floatEtaCenter of each PFregion
std::vector<float> phis_; // floatPhiCenter of each PFregion
};
} // namespace l1t
#endif
176 changes: 176 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#include <unordered_map>

#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"

#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/deregionizer/deregionizer_input.h"
#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/deregionizer/deregionizer_ref.h"

class DeregionizerProducer : public edm::stream::EDProducer<> {
public:
explicit DeregionizerProducer(const edm::ParameterSet &);
~DeregionizerProducer() override;

private:
edm::ParameterSet config_;
edm::EDGetTokenT<l1t::PFCandidateRegionalOutput> token_;
l1ct::DeregionizerEmulator emulator_;
bool debug_;

std::unordered_map<const l1t::PFCandidate *, l1t::PFClusterRef> clusterRefMap_;
std::unordered_map<const l1t::PFCandidate *, l1t::PFTrackRef> trackRefMap_;
std::unordered_map<const l1t::PFCandidate *, l1t::PFCandidate::MuonRef> muonRefMap_;

void produce(edm::Event &, const edm::EventSetup &) override;
void hwToEdm_(const std::vector<l1ct::PuppiObjEmu> &hwOut, std::vector<l1t::PFCandidate> &edmOut) const;
void setRefs_(l1t::PFCandidate &pf, const l1ct::PuppiObjEmu &p) const;
};

DeregionizerProducer::DeregionizerProducer(const edm::ParameterSet &iConfig)
: config_(iConfig),
token_(consumes<l1t::PFCandidateRegionalOutput>(iConfig.getParameter<edm::InputTag>("RegionalPuppiCands"))),
emulator_(iConfig),
debug_(iConfig.getUntrackedParameter<bool>("debug", 0)) {
produces<l1t::PFCandidateCollection>("Puppi");
produces<l1t::PFCandidateCollection>("TruncatedPuppi");
}

DeregionizerProducer::~DeregionizerProducer() {}

void DeregionizerProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
clusterRefMap_.clear();
trackRefMap_.clear();
muonRefMap_.clear();

auto deregColl = std::make_unique<l1t::PFCandidateCollection>();
auto truncColl = std::make_unique<l1t::PFCandidateCollection>();

edm::Handle<l1t::PFCandidateRegionalOutput> src;

iEvent.getByToken(token_, src);

std::vector<float> regionEtas, regionPhis;
std::vector<l1ct::OutputRegion> outputRegions;
std::vector<l1ct::PuppiObjEmu> hwOut;
std::vector<l1t::PFCandidate> edmOut;
std::vector<l1ct::PuppiObjEmu> hwTruncOut;
std::vector<l1t::PFCandidate> edmTruncOut;

if (debug_)
edm::LogPrint("DeregionizerProducer") << "\nRegional Puppi Candidates";
for (unsigned int iReg = 0, nReg = src->nRegions(); iReg < nReg; ++iReg) {
l1ct::OutputRegion tempOutputRegion;

auto region = src->region(iReg);
float eta = src->eta(iReg);
float phi = src->phi(iReg);
if (debug_)
edm::LogPrint("DeregionizerProducer") << "\nRegion " << iReg << "\n"
<< "Eta = " << eta << " and Phi = " << phi << "\n"
<< "###########";
for (int i = 0, n = region.size(); i < n; ++i) {
l1ct::PuppiObjEmu tempPuppi;
const l1t::PFCandidate &cand = region[i];
clusterRefMap_[&cand] = cand.pfCluster();
trackRefMap_[&cand] = cand.pfTrack();
muonRefMap_[&cand] = cand.muon();

tempPuppi.initFromBits(cand.encodedPuppi64());
tempPuppi.srcCand = &cand;
tempOutputRegion.puppi.push_back(tempPuppi);
if (debug_)
edm::LogPrint("DeregionizerProducer") << "pt[" << i << "] = " << tempOutputRegion.puppi.back().hwPt << ", eta["
<< i << "] = " << tempOutputRegion.puppi.back().floatEta() << ", phi["
<< i << "] = " << tempOutputRegion.puppi.back().floatPhi();
}
if (tempOutputRegion.puppi.size() > 0) {
regionEtas.push_back(eta);
regionPhis.push_back(phi);
outputRegions.push_back(tempOutputRegion);
}
}

l1ct::DeregionizerInput in = l1ct::DeregionizerInput(regionEtas, regionPhis, outputRegions);
in.setDebug(debug_);

emulator_.run(in, hwOut, hwTruncOut);

DeregionizerProducer::hwToEdm_(hwOut, edmOut);
DeregionizerProducer::hwToEdm_(hwTruncOut, edmTruncOut);

deregColl->swap(edmOut);
truncColl->swap(edmTruncOut);

iEvent.put(std::move(deregColl), "Puppi");
iEvent.put(std::move(truncColl), "TruncatedPuppi");
}

void DeregionizerProducer::hwToEdm_(const std::vector<l1ct::PuppiObjEmu> &hwOut,
std::vector<l1t::PFCandidate> &edmOut) const {
for (const auto &hwPuppi : hwOut) {
l1t::PFCandidate::ParticleType type;
float mass = 0.13f;
if (hwPuppi.hwId.charged()) {
if (hwPuppi.hwId.isMuon()) {
type = l1t::PFCandidate::Muon;
mass = 0.105;
} else if (hwPuppi.hwId.isElectron()) {
type = l1t::PFCandidate::Electron;
mass = 0.005;
} else
type = l1t::PFCandidate::ChargedHadron;
} else {
type = hwPuppi.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
mass = hwPuppi.hwId.isPhoton() ? 0.0 : 0.5;
}
reco::Particle::PolarLorentzVector p4(hwPuppi.floatPt(), hwPuppi.floatEta(), hwPuppi.floatPhi(), mass);
edmOut.emplace_back(
type, hwPuppi.intCharge(), p4, hwPuppi.floatPuppiW(), hwPuppi.intPt(), hwPuppi.intEta(), hwPuppi.intPhi());
if (hwPuppi.hwId.charged()) {
edmOut.back().setZ0(hwPuppi.floatZ0());
edmOut.back().setDxy(hwPuppi.floatDxy());
edmOut.back().setHwZ0(hwPuppi.hwZ0());
edmOut.back().setHwDxy(hwPuppi.hwDxy());
edmOut.back().setHwTkQuality(hwPuppi.hwTkQuality());
} else {
edmOut.back().setHwPuppiWeight(hwPuppi.hwPuppiW());
edmOut.back().setHwEmID(hwPuppi.hwEmID());
}
edmOut.back().setEncodedPuppi64(hwPuppi.pack().to_uint64());
setRefs_(edmOut.back(), hwPuppi);
}
}

void DeregionizerProducer::setRefs_(l1t::PFCandidate &pf, const l1ct::PuppiObjEmu &p) const {
if (p.srcCand) {
auto match = clusterRefMap_.find(p.srcCand);
if (match == clusterRefMap_.end()) {
throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt "
<< p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
}
pf.setPFCluster(match->second);
}
if (p.srcCand) {
auto match = trackRefMap_.find(p.srcCand);
if (match == trackRefMap_.end()) {
throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.intId() << " pt "
<< p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
}
pf.setPFTrack(match->second);
}
if (p.srcCand) {
auto match = muonRefMap_.find(p.srcCand);
if (match == muonRefMap_.end()) {
throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.intId() << " pt "
<< p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
}
pf.setMuon(match->second);
}
}

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(DeregionizerProducer);
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ l1t::PFJet L1SeedConePFJetProducer::makeJet_SW(const std::vector<edm::Ptr<l1t::P

std::vector<l1t::PFJet> L1SeedConePFJetProducer::processEvent_SW(std::vector<edm::Ptr<l1t::PFCandidate>>& work) const {
// The floating point algorithm simulation
std::sort(work.begin(), work.end(), [](edm::Ptr<l1t::PFCandidate> i, edm::Ptr<l1t::PFCandidate> j) {
std::stable_sort(work.begin(), work.end(), [](edm::Ptr<l1t::PFCandidate> i, edm::Ptr<l1t::PFCandidate> j) {
return (i->pt() > j->pt());
});
std::vector<l1t::PFJet> jets;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ void L1TCorrelatorLayer1Producer::putPuppi(edm::Event &iEvent) const {
setRefs_(coll->back(), p);
nobj.push_back(coll->size() - 1);
}
reg->addRegion(nobj);
reg->addRegion(nobj, event_.pfinputs[ir].region.floatEtaCenter(), event_.pfinputs[ir].region.floatPhiCenter());
}
iEvent.put(std::move(coll), "Puppi");
iEvent.put(std::move(reg), "PuppiRegional");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void L1TPFCandMultiMerger::produce(edm::StreamID, edm::Event& iEvent, const edm:
for (auto iter = region.begin(), iend = region.end(); iter != iend; ++iter) {
keys.push_back(iter.idx() + offset);
}
regout->addRegion(keys);
regout->addRegion(keys, src.eta(ireg), src.phi(ireg));
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/python/DeregionizerProducer_cfi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import FWCore.ParameterSet.Config as cms

DeregionizerProducer = cms.EDProducer("DeregionizerProducer",
RegionalPuppiCands = cms.InputTag("l1ctLayer1","PuppiRegional"),
nPuppiFinalBuffer = cms.uint32(128),
nPuppiPerClk = cms.uint32(6),
nPuppiFirstBuffers = cms.uint32(12),
nPuppiSecondBuffers = cms.uint32(32),
nPuppiThirdBuffers = cms.uint32(64),
debug = cms.untracked.bool(False)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <fstream>
#include <cmath>
#include <vector>
#include "deregionizer_input.h"

#ifdef CMSSW_GIT_HASH
#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h"
#else
#include "../../utils/dbgPrintf.h"
#endif

l1ct::DeregionizerInput::DeregionizerInput(std::vector<float> &regionEtaCenter,
std::vector<float> &regionPhiCenter,
const std::vector<l1ct::OutputRegion> &inputRegions)
: regionEtaCenter_(regionEtaCenter), regionPhiCenter_(regionPhiCenter) {
orderedInRegionsPuppis_ = std::vector<std::vector<std::vector<l1ct::PuppiObjEmu> > >(nEtaRegions);
for (int i = 0, n = nEtaRegions; i < n; i++)
orderedInRegionsPuppis_[i].resize(nPhiRegions);
initRegions(inputRegions);
}

// +pi read first & account for 2 small eta regions per phi slice
unsigned int l1ct::DeregionizerInput::orderRegionsInPhi(const float eta, const float phi, const float etaComp) const {
unsigned int y;
if (fabs(phi) < 0.35)
y = (eta < etaComp ? 0 : 1);
else if (fabs(phi) < 1.05)
y = (phi > 0 ? (eta < etaComp ? 2 : 3) : (eta < etaComp ? 16 : 17));
else if (fabs(phi) < 1.75)
y = (phi > 0 ? (eta < etaComp ? 4 : 5) : (eta < etaComp ? 14 : 15));
else if (fabs(phi) < 2.45)
y = (phi > 0 ? (eta < etaComp ? 6 : 7) : (eta < etaComp ? 12 : 13));
else
y = (phi > 0 ? (eta < etaComp ? 8 : 9) : (eta < etaComp ? 10 : 11));
return y;
}

void l1ct::DeregionizerInput::initRegions(const std::vector<l1ct::OutputRegion> &inputRegions) {
for (int i = 0, n = inputRegions.size(); i < n; i++) {
unsigned int x, y;
float eta = regionEtaCenter_[i];
float phi = regionPhiCenter_[i];

if (fabs(eta) < 0.5) {
x = 0;
y = orderRegionsInPhi(eta, phi, 0.0);
} else if (fabs(eta) < 1.5) {
x = (eta < 0.0 ? 1 : 2);
y = (eta < 0.0 ? orderRegionsInPhi(eta, phi, -1.0) : orderRegionsInPhi(eta, phi, 1.0));
} else if (fabs(eta) < 2.5) {
x = (eta < 0.0 ? 3 : 4);
y = orderRegionsInPhi(eta, phi, 999.0); // Send all candidates in 3 clks, then wait 3 clks for the barrel
} else /*if ( fabs(eta) < 3.0 )*/ {
x = 5;
y = orderRegionsInPhi(eta, phi, 0.0); // Send eta<0 in 3 clks, eta>0 in the next 3 clks
}
/*else x = 6;*/ // HF

orderedInRegionsPuppis_[x][y].insert(orderedInRegionsPuppis_[x][y].end(),
inputRegions[i].puppi.begin(),
inputRegions[i].puppi.end()); // For now, merging HF with forward HGCal

while (!orderedInRegionsPuppis_[x][y].empty() && orderedInRegionsPuppis_[x][y].back().hwPt == 0)
orderedInRegionsPuppis_[x][y].pop_back(); // Zero suppression
}
}

void l1ct::DeregionizerInput::orderRegions(int order[nEtaRegions]) {
std::vector<std::vector<std::vector<l1ct::PuppiObjEmu> > > tmpOrderedInRegionsPuppis;
for (int i = 0, n = nEtaRegions; i < n; i++)
tmpOrderedInRegionsPuppis.push_back(orderedInRegionsPuppis_[order[i]]);
orderedInRegionsPuppis_ = tmpOrderedInRegionsPuppis;

if (debug_) {
for (int i = 0, nx = orderedInRegionsPuppis_.size(); i < nx; i++) {
dbgCout() << "\n";
dbgCout() << "Eta region index : " << i << "\n";
for (int j = 0, ny = orderedInRegionsPuppis_[i].size(); j < ny; j++) {
dbgCout() << " ---> Phi region index : " << j << "\n";
for (int iPup = 0, nPup = orderedInRegionsPuppis_[i][j].size(); iPup < nPup; iPup++) {
dbgCout() << " > puppi[" << iPup << "]"
<< " pt = " << orderedInRegionsPuppis_[i][j][iPup].hwPt << "\n";
}
}
dbgCout() << " ----------------- "
<< "\n";
}
dbgCout() << "Regions ordered!"
<< "\n";
dbgCout() << "\n";
}
}
Loading

0 comments on commit 686d277

Please sign in to comment.