File indexing completed on 2023-12-05 03:12:13
0001 #include "DataFormats/L1TCorrelator/interface/TkElectron.h"
0002 #include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h"
0003 #include "DataFormats/L1TCorrelator/interface/TkEm.h"
0004 #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h"
0005 #include "DataFormats/L1Trigger/interface/EGamma.h"
0006 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0007
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/global/EDProducer.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/Utilities/interface/InputTag.h"
0012 #include "FWCore/Utilities/interface/transform.h"
0013
0014 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0015 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h"
0016 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h"
0017 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h"
0018
0019 #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h"
0020 #include "L1Trigger/DemonstratorTools/interface/utilities.h"
0021
0022 #include <iostream>
0023 #include <vector>
0024
0025 using namespace l1ct;
0026
0027 class L1TCtL2EgProducer : public edm::global::EDProducer<> {
0028 public:
0029 explicit L1TCtL2EgProducer(const edm::ParameterSet &);
0030 ~L1TCtL2EgProducer() override;
0031
0032 private:
0033 ap_uint<64> encodeLayer1(const EGIsoObjEmu &egiso) const;
0034 ap_uint<128> encodeLayer1(const EGIsoEleObjEmu &egiso) const;
0035
0036 std::vector<ap_uint<64>> encodeLayer1(const std::vector<EGIsoObjEmu> &photons) const;
0037 std::vector<ap_uint<64>> encodeLayer1(const std::vector<EGIsoEleObjEmu> &electrons) const;
0038
0039 std::vector<ap_uint<64>> encodeLayer1EgObjs(unsigned int nObj,
0040 const std::vector<EGIsoObjEmu> &photons,
0041 const std::vector<EGIsoEleObjEmu> &electrons) const;
0042
0043 void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
0044
0045 void endJob() override;
0046
0047 typedef TTTrack<Ref_Phase2TrackerDigi_> L1TTTrackType;
0048 typedef std::vector<std::pair<edm::Ptr<l1t::L1Candidate>, edm::Ptr<L1TTTrackType>>> ConstituentPtrVector;
0049
0050 void convertToEmu(const l1t::TkElectron &tkele,
0051 ConstituentPtrVector &constituentsPtrs,
0052 l1ct::OutputBoard &boarOut) const;
0053 void convertToEmu(const l1t::TkEm &tkele, ConstituentPtrVector &constituentsPtrs, l1ct::OutputBoard &boarOut) const;
0054 void convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const;
0055
0056 template <class T>
0057 class PFInstanceInputs {
0058 public:
0059 typedef std::vector<std::pair<edm::EDGetTokenT<T>, std::vector<int>>> InputTokenAndChannels;
0060 PFInstanceInputs(L1TCtL2EgProducer *prod, const std::vector<edm::ParameterSet> &confs) {
0061 for (const auto &conf : confs) {
0062 const auto &producer_tag = conf.getParameter<edm::InputTag>("pfProducer");
0063 tokensAndChannels_.push_back(std::make_pair(
0064 prod->consumes<T>(edm::InputTag(producer_tag.label(), producer_tag.instance(), producer_tag.process())),
0065 conf.getParameter<std::vector<int>>("channels")));
0066 }
0067 }
0068
0069 const InputTokenAndChannels &tokensAndChannels() const { return tokensAndChannels_; }
0070
0071 private:
0072 InputTokenAndChannels tokensAndChannels_;
0073 };
0074
0075 class PatternWriter {
0076 public:
0077 PatternWriter(const edm::ParameterSet &conf) : dataWriter_(nullptr) {
0078 unsigned int nFramesPerBX = conf.getParameter<uint32_t>("nFramesPerBX");
0079
0080 std::map<l1t::demo::LinkId, std::pair<l1t::demo::ChannelSpec, std::vector<size_t>>> channelSpecs;
0081
0082 for (const auto &channelConf : conf.getParameter<std::vector<edm::ParameterSet>>("channels")) {
0083 unsigned int inTMUX = channelConf.getParameter<uint32_t>("TMUX");
0084 unsigned int eventGap =
0085 inTMUX * nFramesPerBX - channelConf.getParameter<uint32_t>("nWords");
0086
0087 std::vector<uint32_t> chns = channelConf.getParameter<std::vector<uint32_t>>("channels");
0088 channelSpecs[l1t::demo::LinkId{channelConf.getParameter<std::string>("interface"),
0089 channelConf.getParameter<uint32_t>("id")}] =
0090 std::make_pair(l1t::demo::ChannelSpec{inTMUX, eventGap},
0091 std::vector<size_t>(std::begin(chns), std::end(chns)));
0092 }
0093
0094 dataWriter_ = std::make_unique<l1t::demo::BoardDataWriter>(
0095 l1t::demo::parseFileFormat(conf.getParameter<std::string>("format")),
0096 conf.getParameter<std::string>("outputFilename"),
0097 conf.getParameter<std::string>("outputFileExtension"),
0098 nFramesPerBX,
0099 conf.getParameter<uint32_t>("TMUX"),
0100 conf.getParameter<uint32_t>("maxLinesPerFile"),
0101 channelSpecs);
0102 }
0103
0104 void addEvent(const l1t::demo::EventData &eventData) { dataWriter_->addEvent(eventData); }
0105
0106 void flush() { dataWriter_->flush(); }
0107
0108 private:
0109 std::unique_ptr<l1t::demo::BoardDataWriter> dataWriter_;
0110 };
0111
0112 template <class TT, class T>
0113 void merge(const PFInstanceInputs<T> &instance,
0114 edm::Event &iEvent,
0115 ConstituentPtrVector &constituentsPtrs,
0116 std::unique_ptr<TT> &out) const {
0117 edm::Handle<T> handle;
0118 for (const auto &tokenAndChannel : instance.tokensAndChannels()) {
0119 iEvent.getByToken(tokenAndChannel.first, handle);
0120 populate(out, handle, tokenAndChannel.second, constituentsPtrs);
0121 }
0122 }
0123
0124 template <class TT, class T>
0125 void populate(std::unique_ptr<T> &out,
0126 const edm::Handle<TT> &in,
0127 const std::vector<int> &links,
0128 ConstituentPtrVector &constituentsPtrs) const {
0129 assert(links.size() == in->nRegions());
0130 for (unsigned int iBoard = 0, nBoard = in->nRegions(); iBoard < nBoard; ++iBoard) {
0131 auto region = in->region(iBoard);
0132 int linkID = links[iBoard];
0133 if (linkID < 0)
0134 continue;
0135
0136 for (const auto &obj : region) {
0137 convertToEmu(obj, constituentsPtrs, out->at(linkID));
0138 }
0139 }
0140 }
0141
0142 void populate(std::unique_ptr<BXVector<l1t::EGamma>> &out,
0143 const edm::Handle<BXVector<l1t::EGamma>> &in,
0144 const std::vector<int> &links,
0145 ConstituentPtrVector &constituentsPtrs) const {
0146 for (int bx = in->getFirstBX(); bx <= in->getLastBX(); bx++) {
0147 for (auto egee_itr = in->begin(bx); egee_itr != in->end(bx); egee_itr++) {
0148 out->push_back(bx, *egee_itr);
0149 }
0150 }
0151 }
0152
0153 template <class Tout, class Tin>
0154 void putEgObjects(edm::Event &iEvent,
0155 const ConstituentPtrVector &constituentsPtrs,
0156 const std::string &label,
0157 const std::vector<Tin> emulated) const {
0158 auto egobjs = std::make_unique<Tout>();
0159 for (const auto &emu : emulated) {
0160 if (emu.hwPt == 0)
0161 continue;
0162 auto obj = convertFromEmu(emu, constituentsPtrs);
0163 egobjs->push_back(obj);
0164 }
0165 iEvent.put(std::move(egobjs), label);
0166 }
0167
0168 l1t::TkEm convertFromEmu(const l1ct::EGIsoObjEmu &emu, const ConstituentPtrVector &constituentsPtrs) const;
0169 l1t::TkElectron convertFromEmu(const l1ct::EGIsoEleObjEmu &emu, const ConstituentPtrVector &constituentsPtrs) const;
0170
0171 PFInstanceInputs<BXVector<l1t::EGamma>> tkEGInputs_;
0172 PFInstanceInputs<l1t::TkEmRegionalOutput> tkEmInputs_;
0173 PFInstanceInputs<l1t::TkElectronRegionalOutput> tkEleInputs_;
0174 std::string tkEGInstanceLabel_;
0175 std::string tkEmInstanceLabel_;
0176 std::string tkEleInstanceLabel_;
0177 l1ct::L2EgSorterEmulator l2egsorter;
0178 l1ct::L2EgEncoderEmulator l2encoder;
0179 edm::EDGetTokenT<std::vector<l1t::PFCandidate>> pfObjsToken_;
0180 l1ct::L1EGPuppiIsoAlgo l2EgPuppiIsoAlgo_;
0181 l1ct::L1EGPuppiIsoAlgo l2ElePuppiIsoAlgo_;
0182 bool doInPtrn_;
0183 bool doOutPtrn_;
0184 std::unique_ptr<PatternWriter> inPtrnWrt_;
0185 std::unique_ptr<PatternWriter> outPtrnWrt_;
0186 };
0187
0188 L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf)
0189 : tkEGInputs_(this, conf.getParameter<std::vector<edm::ParameterSet>>("tkEgs")),
0190 tkEmInputs_(this, conf.getParameter<std::vector<edm::ParameterSet>>("tkEms")),
0191 tkEleInputs_(this, conf.getParameter<std::vector<edm::ParameterSet>>("tkElectrons")),
0192 tkEGInstanceLabel_(conf.getParameter<std::string>("egStaInstanceLabel")),
0193 tkEmInstanceLabel_(conf.getParameter<std::string>("tkEmInstanceLabel")),
0194 tkEleInstanceLabel_(conf.getParameter<std::string>("tkEleInstanceLabel")),
0195 l2egsorter(conf.getParameter<edm::ParameterSet>("sorter")),
0196 l2encoder(conf.getParameter<edm::ParameterSet>("encoder")),
0197 pfObjsToken_(consumes<std::vector<l1t::PFCandidate>>(conf.getParameter<edm::InputTag>("l1PFObjects"))),
0198 l2EgPuppiIsoAlgo_(conf.getParameter<edm::ParameterSet>("puppiIsoParametersTkEm")),
0199 l2ElePuppiIsoAlgo_(conf.getParameter<edm::ParameterSet>("puppiIsoParametersTkEle")),
0200 doInPtrn_(conf.getParameter<bool>("writeInPattern")),
0201 doOutPtrn_(conf.getParameter<bool>("writeOutPattern")),
0202 inPtrnWrt_(nullptr),
0203 outPtrnWrt_(nullptr) {
0204 produces<BXVector<l1t::EGamma>>(tkEGInstanceLabel_);
0205 produces<l1t::TkEmCollection>(tkEmInstanceLabel_);
0206 produces<l1t::TkElectronCollection>(tkEleInstanceLabel_);
0207
0208 if (doInPtrn_) {
0209 inPtrnWrt_ = std::make_unique<PatternWriter>(conf.getParameter<edm::ParameterSet>("inPatternFile"));
0210 }
0211 if (doOutPtrn_) {
0212 outPtrnWrt_ = std::make_unique<PatternWriter>(conf.getParameter<edm::ParameterSet>("outPatternFile"));
0213 }
0214 }
0215
0216 L1TCtL2EgProducer::~L1TCtL2EgProducer() {}
0217
0218 ap_uint<64> L1TCtL2EgProducer::encodeLayer1(const EGIsoObjEmu &egiso) const {
0219 ap_uint<64> ret = 0;
0220 ret(EGIsoObjEmu::BITWIDTH, 0) = egiso.pack();
0221 return ret;
0222 }
0223
0224 ap_uint<128> L1TCtL2EgProducer::encodeLayer1(const EGIsoEleObjEmu &egiso) const {
0225 ap_uint<128> ret = 0;
0226 ret(EGIsoEleObjEmu::BITWIDTH, 0) = egiso.pack();
0227 return ret;
0228 }
0229
0230 std::vector<ap_uint<64>> L1TCtL2EgProducer::encodeLayer1(const std::vector<EGIsoObjEmu> &photons) const {
0231 std::vector<ap_uint<64>> ret;
0232 ret.reserve(photons.size());
0233 for (const auto &phot : photons) {
0234 ret.push_back(encodeLayer1(phot));
0235 }
0236 return ret;
0237 }
0238
0239 std::vector<ap_uint<64>> L1TCtL2EgProducer::encodeLayer1(const std::vector<EGIsoEleObjEmu> &electrons) const {
0240 std::vector<ap_uint<64>> ret;
0241 ret.reserve(2 * electrons.size());
0242 for (const auto &ele : electrons) {
0243 auto eleword = encodeLayer1(ele);
0244 ret.push_back(eleword(63, 0));
0245 ret.push_back(eleword(127, 64));
0246 }
0247 return ret;
0248 }
0249
0250 std::vector<ap_uint<64>> L1TCtL2EgProducer::encodeLayer1EgObjs(unsigned int nObj,
0251 const std::vector<EGIsoObjEmu> &photons,
0252 const std::vector<EGIsoEleObjEmu> &electrons) const {
0253 std::vector<ap_uint<64>> ret;
0254 auto encoded_photons = encodeLayer1(photons);
0255 encoded_photons.resize(nObj, {0});
0256 auto encoded_eles = encodeLayer1(electrons);
0257 encoded_eles.resize(2 * nObj, {0});
0258
0259 std::copy(encoded_photons.begin(), encoded_photons.end(), std::back_inserter(ret));
0260 std::copy(encoded_eles.begin(), encoded_eles.end(), std::back_inserter(ret));
0261
0262 return ret;
0263 }
0264
0265 void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &) const {
0266 ConstituentPtrVector constituents;
0267
0268 auto outEgs = std::make_unique<BXVector<l1t::EGamma>>();
0269 merge(tkEGInputs_, iEvent, constituents, outEgs);
0270 iEvent.put(std::move(outEgs), tkEGInstanceLabel_);
0271
0272 auto boards = std::make_unique<std::vector<l1ct::OutputBoard>>(l2egsorter.nInputBoards());
0273
0274 merge(tkEleInputs_, iEvent, constituents, boards);
0275 merge(tkEmInputs_, iEvent, constituents, boards);
0276
0277 if (doInPtrn_) {
0278 l1t::demo::EventData inData;
0279 for (unsigned int ibrd = 0; ibrd < boards->size(); ibrd++) {
0280 inData.add(
0281 {"eglayer1", ibrd},
0282 encodeLayer1EgObjs(l2egsorter.nInputObjPerBoard(), (*boards)[ibrd].egphoton, (*boards)[ibrd].egelectron));
0283 }
0284 inPtrnWrt_->addEvent(inData);
0285 }
0286
0287 std::vector<EGIsoObjEmu> out_photons_emu;
0288 std::vector<EGIsoEleObjEmu> out_eles_emu;
0289 l2egsorter.run(*boards, out_photons_emu, out_eles_emu);
0290
0291
0292 auto &pfObjs = iEvent.get(pfObjsToken_);
0293 l1ct::PuppiObjs puppiObjs;
0294 convertToPuppi(pfObjs, puppiObjs);
0295 l2EgPuppiIsoAlgo_.run(out_photons_emu, puppiObjs);
0296 l2ElePuppiIsoAlgo_.run(out_eles_emu, puppiObjs);
0297
0298 if (doOutPtrn_) {
0299 l1t::demo::EventData outData;
0300 outData.add({"eglayer2", 0}, l2encoder.encodeLayer2EgObjs(out_photons_emu, out_eles_emu));
0301 outPtrnWrt_->addEvent(outData);
0302 }
0303
0304 putEgObjects<l1t::TkEmCollection>(iEvent, constituents, tkEmInstanceLabel_, out_photons_emu);
0305 putEgObjects<l1t::TkElectronCollection>(iEvent, constituents, tkEleInstanceLabel_, out_eles_emu);
0306 }
0307
0308 void L1TCtL2EgProducer::endJob() {
0309
0310 if (doOutPtrn_)
0311 outPtrnWrt_->flush();
0312 if (doInPtrn_)
0313 inPtrnWrt_->flush();
0314 }
0315
0316 void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele,
0317 ConstituentPtrVector &constituentsPtrs,
0318 l1ct::OutputBoard &boarOut) const {
0319 EGIsoEleObjEmu emu;
0320 emu.initFromBits(tkele.egBinaryWord<EGIsoEleObj::BITWIDTH>());
0321 emu.srcCluster = nullptr;
0322 emu.srcTrack = nullptr;
0323
0324 constituentsPtrs.push_back(std::make_pair(tkele.egCaloPtr(), tkele.trkPtr()));
0325 emu.src_idx = constituentsPtrs.size() - 1;
0326
0327
0328 emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol() * tkele.pt()));
0329 emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol() * tkele.pt()));
0330 emu.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkele.puppiIsol() * tkele.pt()));
0331
0332 boarOut.egelectron.push_back(emu);
0333 }
0334
0335 void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem,
0336 ConstituentPtrVector &constituentsPtrs,
0337 l1ct::OutputBoard &boarOut) const {
0338 EGIsoObjEmu emu;
0339 emu.initFromBits(tkem.egBinaryWord<EGIsoObj::BITWIDTH>());
0340 emu.srcCluster = nullptr;
0341 constituentsPtrs.push_back(std::make_pair(tkem.egCaloPtr(), edm::Ptr<L1TTTrackType>()));
0342 emu.src_idx = constituentsPtrs.size() - 1;
0343
0344 emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol() * tkem.pt()));
0345 emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol() * tkem.pt()));
0346 emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol() * tkem.pt()));
0347 emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV() * tkem.pt()));
0348 emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV() * tkem.pt()));
0349
0350 boarOut.egphoton.push_back(emu);
0351 }
0352
0353 void L1TCtL2EgProducer::convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const {
0354 for (const auto &l1PFCand : l1PFCands) {
0355 l1ct::PuppiObj obj;
0356 obj.initFromBits(l1PFCand.encodedPuppi64());
0357 puppiObjs.emplace_back(obj);
0358 }
0359 }
0360
0361 l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso,
0362 const ConstituentPtrVector &constituentsPtrs) const {
0363
0364
0365 const auto gteg = egiso.toGT();
0366 reco::Candidate::PolarLorentzVector mom(
0367 l1gt::Scales::floatPt(gteg.v3.pt), l1gt::Scales::floatEta(gteg.v3.eta), l1gt::Scales::floatPhi(gteg.v3.phi), 0.);
0368
0369 l1t::TkEm tkem(reco::Candidate::LorentzVector(mom),
0370 constituentsPtrs[egiso.src_idx].first,
0371 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIso),
0372 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIsoPV));
0373 tkem.setHwQual(gteg.quality);
0374 tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso));
0375 tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV));
0376 tkem.setPuppiIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIso));
0377 tkem.setEgBinaryWord(gteg.pack(), l1t::TkEm::HWEncoding::GT);
0378 return tkem;
0379 }
0380
0381 l1t::TkElectron L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoEleObjEmu &egele,
0382 const ConstituentPtrVector &constituentsPtrs) const {
0383
0384
0385 const auto gteg = egele.toGT();
0386 reco::Candidate::PolarLorentzVector mom(
0387 l1gt::Scales::floatPt(gteg.v3.pt), l1gt::Scales::floatEta(gteg.v3.eta), l1gt::Scales::floatPhi(gteg.v3.phi), 0.);
0388
0389 l1t::TkElectron tkele(reco::Candidate::LorentzVector(mom),
0390 constituentsPtrs[egele.src_idx].first,
0391 constituentsPtrs[egele.src_idx].second,
0392 egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso));
0393 tkele.setHwQual(gteg.quality);
0394 tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso));
0395 tkele.setPuppiIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PuppiIso));
0396 tkele.setEgBinaryWord(gteg.pack(), l1t::TkElectron::HWEncoding::GT);
0397 tkele.setIdScore(egele.floatIDScore());
0398 tkele.setCharge(egele.intCharge());
0399 return tkele;
0400 }
0401
0402 #include "FWCore/Framework/interface/MakerMacros.h"
0403 DEFINE_FWK_MODULE(L1TCtL2EgProducer);