File indexing completed on 2022-10-01 01:02:12
0001
0002 #include <memory>
0003 #include <algorithm>
0004 #include <fstream>
0005 #include <cstdio>
0006
0007
0008 #include "FWCore/Framework/interface/Frameworkfwd.h"
0009 #include "FWCore/Framework/interface/stream/EDProducer.h"
0010 #include "FWCore/Framework/interface/Event.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/ParameterSet/interface/FileInPath.h"
0013
0014 #include "DataFormats/Common/interface/View.h"
0015 #include "DataFormats/Common/interface/RefToPtr.h"
0016 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0017 #include "DataFormats/L1Trigger/interface/Vertex.h"
0018 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0019
0020 #include "DataFormats/Math/interface/deltaR.h"
0021
0022 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h"
0023 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h"
0024 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h"
0025 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h"
0026 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h"
0027 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h"
0028 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h"
0029 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h"
0030 #include "L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h"
0031 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h"
0032 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h"
0033 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h"
0034 #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h"
0035
0036 #include "DataFormats/L1TCorrelator/interface/TkElectron.h"
0037 #include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h"
0038 #include "DataFormats/L1Trigger/interface/EGamma.h"
0039 #include "DataFormats/L1TCorrelator/interface/TkEm.h"
0040 #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h"
0041
0042
0043 class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> {
0044 public:
0045 explicit L1TCorrelatorLayer1Producer(const edm::ParameterSet &);
0046 ~L1TCorrelatorLayer1Producer() override;
0047
0048 private:
0049 edm::ParameterSet config_;
0050
0051 bool hasTracks_;
0052 edm::EDGetTokenT<l1t::PFTrackCollection> tkCands_;
0053 float trkPt_;
0054 bool emuTkVtx_;
0055 edm::EDGetTokenT<std::vector<l1t::Vertex>> extTkVtx_;
0056 edm::EDGetTokenT<std::vector<l1t::VertexWord>> tkVtxEmu_;
0057 int nVtx_;
0058
0059 edm::EDGetTokenT<l1t::SAMuonCollection> muCands_;
0060
0061 std::vector<edm::EDGetTokenT<l1t::PFClusterCollection>> emCands_;
0062 std::vector<edm::EDGetTokenT<l1t::PFClusterCollection>> hadCands_;
0063
0064 float emPtCut_, hadPtCut_;
0065
0066 l1ct::Event event_;
0067 std::unique_ptr<l1ct::TrackInputEmulator> trackInput_;
0068 std::unique_ptr<l1ct::GMTMuonDecoderEmulator> muonInput_;
0069 std::unique_ptr<l1ct::RegionizerEmulator> regionizer_;
0070 std::unique_ptr<l1ct::PFAlgoEmulatorBase> l1pfalgo_;
0071 std::unique_ptr<l1ct::LinPuppiEmulator> l1pualgo_;
0072 std::unique_ptr<l1ct::PFTkEGAlgoEmulator> l1tkegalgo_;
0073 std::unique_ptr<l1ct::PFTkEGSorterEmulator> l1tkegsorter_;
0074
0075 bool writeEgSta_;
0076
0077 const std::string regionDumpName_;
0078 bool writeRawHgcalCluster_;
0079 std::fstream fRegionDump_;
0080 const std::vector<edm::ParameterSet> patternWriterConfigs_;
0081 std::vector<std::unique_ptr<L1TCorrelatorLayer1PatternFileWriter>> patternWriters_;
0082
0083
0084 float debugEta_, debugPhi_, debugR_;
0085
0086
0087 std::unordered_map<const l1t::PFCluster *, l1t::PFClusterRef> clusterRefMap_;
0088 std::unordered_map<const l1t::PFTrack *, l1t::PFTrackRef> trackRefMap_;
0089 std::unordered_map<const l1t::SAMuon *, l1t::PFCandidate::MuonRef> muonRefMap_;
0090
0091
0092 void beginStream(edm::StreamID) override;
0093 void endStream() override;
0094 void produce(edm::Event &, const edm::EventSetup &) override;
0095 void addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent);
0096
0097 void initSectorsAndRegions(const edm::ParameterSet &iConfig);
0098 void initEvent(const edm::Event &e);
0099
0100 void addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref);
0101 void addMuon(const l1t::SAMuon &t, l1t::PFCandidate::MuonRef ref);
0102 void addHadCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref);
0103 void addEmCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref);
0104
0105 void addDecodedTrack(l1ct::DetectorSector<l1ct::TkObjEmu> &sec, const l1t::PFTrack &t);
0106 void addDecodedMuon(l1ct::DetectorSector<l1ct::MuObjEmu> &sec, const l1t::SAMuon &t);
0107 void addDecodedHadCalo(l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec, const l1t::PFCluster &t);
0108 void addDecodedEmCalo(l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec, const l1t::PFCluster &t);
0109
0110 void addRawHgcalCluster(l1ct::DetectorSector<ap_uint<256>> &sec, const l1t::PFCluster &c);
0111
0112
0113 std::unique_ptr<l1t::PFCandidateCollection> fetchHadCalo() const;
0114 std::unique_ptr<l1t::PFCandidateCollection> fetchEmCalo() const;
0115 std::unique_ptr<l1t::PFCandidateCollection> fetchTracks() const;
0116 std::unique_ptr<l1t::PFCandidateCollection> fetchPF() const;
0117 void putPuppi(edm::Event &iEvent) const;
0118
0119 void putEgStaObjects(edm::Event &iEvent,
0120 const std::string &egLablel,
0121 std::vector<edm::Ref<BXVector<l1t::EGamma>>> &egsta_refs);
0122 void putEgObjects(edm::Event &iEvent,
0123 const bool writeEgSta,
0124 const std::vector<edm::Ref<BXVector<l1t::EGamma>>> &egsta_refs,
0125 const std::string &tkEmLabel,
0126 const std::string &tkEmPerBoardLabel,
0127 const std::string &tkEleLabel,
0128 const std::string &tkElePerBoardLabel) const;
0129
0130 template <typename T>
0131 void setRefs_(l1t::PFCandidate &pf, const T &p) const;
0132
0133 void doVertexings(std::vector<float> &pvdz) const;
0134
0135 enum InputType { caloType = 0, emcaloType = 1, trackType = 2, l1muType = 3 };
0136 static constexpr const char *inputTypeName[l1muType + 1] = {"Calo", "EmCalo", "TK", "Mu"};
0137 std::unique_ptr<std::vector<unsigned>> vecSecInput(InputType i) const;
0138 std::unique_ptr<std::vector<unsigned>> vecRegInput(InputType i) const;
0139 typedef l1ct::OutputRegion::ObjType OutputType;
0140 std::unique_ptr<std::vector<unsigned>> vecOutput(OutputType i, bool usePuppi) const;
0141 std::pair<unsigned int, unsigned int> totAndMax(const std::vector<unsigned> &perRegion) const;
0142 };
0143
0144
0145
0146
0147 L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet &iConfig)
0148 : config_(iConfig),
0149 hasTracks_(!iConfig.getParameter<edm::InputTag>("tracks").label().empty()),
0150 tkCands_(hasTracks_ ? consumes<l1t::PFTrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"))
0151 : edm::EDGetTokenT<l1t::PFTrackCollection>()),
0152 trkPt_(iConfig.getParameter<double>("trkPtCut")),
0153 muCands_(consumes<l1t::SAMuonCollection>(iConfig.getParameter<edm::InputTag>("muons"))),
0154 emPtCut_(iConfig.getParameter<double>("emPtCut")),
0155 hadPtCut_(iConfig.getParameter<double>("hadPtCut")),
0156 regionizer_(nullptr),
0157 l1pfalgo_(nullptr),
0158 l1pualgo_(nullptr),
0159 l1tkegalgo_(nullptr),
0160 l1tkegsorter_(nullptr),
0161 regionDumpName_(iConfig.getUntrackedParameter<std::string>("dumpFileName", "")),
0162 writeRawHgcalCluster_(iConfig.getUntrackedParameter<bool>("writeRawHgcalCluster", false)),
0163 patternWriterConfigs_(iConfig.getUntrackedParameter<std::vector<edm::ParameterSet>>(
0164 "patternWriters", std::vector<edm::ParameterSet>())),
0165 debugEta_(iConfig.getUntrackedParameter<double>("debugEta", 0)),
0166 debugPhi_(iConfig.getUntrackedParameter<double>("debugPhi", 0)),
0167 debugR_(iConfig.getUntrackedParameter<double>("debugR", -1)) {
0168 produces<l1t::PFCandidateCollection>("PF");
0169 produces<l1t::PFCandidateCollection>("Puppi");
0170 produces<l1t::PFCandidateRegionalOutput>("PuppiRegional");
0171
0172 produces<l1t::PFCandidateCollection>("EmCalo");
0173 produces<l1t::PFCandidateCollection>("Calo");
0174 produces<l1t::PFCandidateCollection>("TK");
0175 #if 0
0176 produces<l1t::PFCandidateCollection>("TKVtx");
0177 #endif
0178
0179 for (const auto &tag : iConfig.getParameter<std::vector<edm::InputTag>>("emClusters")) {
0180 emCands_.push_back(consumes<l1t::PFClusterCollection>(tag));
0181 }
0182 for (const auto &tag : iConfig.getParameter<std::vector<edm::InputTag>>("hadClusters")) {
0183 hadCands_.push_back(consumes<l1t::PFClusterCollection>(tag));
0184 }
0185
0186 if (hasTracks_) {
0187 const std::string &tkInAlgo = iConfig.getParameter<std::string>("trackInputConversionAlgo");
0188 if (tkInAlgo == "Emulator") {
0189 trackInput_ = std::make_unique<l1ct::TrackInputEmulator>(
0190 iConfig.getParameter<edm::ParameterSet>("trackInputConversionParameters"));
0191 } else if (tkInAlgo != "Ideal")
0192 throw cms::Exception("Configuration", "Unsupported trackInputConversionAlgo");
0193 }
0194
0195 const std::string &muInAlgo = iConfig.getParameter<std::string>("muonInputConversionAlgo");
0196 if (muInAlgo == "Emulator") {
0197 muonInput_ = std::make_unique<l1ct::GMTMuonDecoderEmulator>(
0198 iConfig.getParameter<edm::ParameterSet>("muonInputConversionParameters"));
0199 } else if (muInAlgo != "Ideal")
0200 throw cms::Exception("Configuration", "Unsupported muonInputConversionAlgo");
0201
0202 const std::string ®algo = iConfig.getParameter<std::string>("regionizerAlgo");
0203 if (regalgo == "Ideal") {
0204 regionizer_ =
0205 std::make_unique<l1ct::RegionizerEmulator>(iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0206 } else if (regalgo == "Multififo") {
0207 regionizer_ = std::make_unique<l1ct::MultififoRegionizerEmulator>(
0208 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0209 } else if (regalgo == "TDR") {
0210 regionizer_ = std::make_unique<l1ct::TDRRegionizerEmulator>(
0211 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0212 } else
0213 throw cms::Exception("Configuration", "Unsupported regionizerAlgo");
0214
0215 const std::string &algo = iConfig.getParameter<std::string>("pfAlgo");
0216 if (algo == "PFAlgo3") {
0217 l1pfalgo_ = std::make_unique<l1ct::PFAlgo3Emulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0218 } else if (algo == "PFAlgo2HGC") {
0219 l1pfalgo_ = std::make_unique<l1ct::PFAlgo2HGCEmulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0220 } else if (algo == "PFAlgoDummy") {
0221 l1pfalgo_ =
0222 std::make_unique<l1ct::PFAlgoDummyEmulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0223 } else
0224 throw cms::Exception("Configuration", "Unsupported pfAlgo");
0225
0226 const std::string &pualgo = iConfig.getParameter<std::string>("puAlgo");
0227 if (pualgo == "LinearizedPuppi") {
0228 l1pualgo_ = std::make_unique<l1ct::LinPuppiEmulator>(iConfig.getParameter<edm::ParameterSet>("puAlgoParameters"));
0229 } else
0230 throw cms::Exception("Configuration", "Unsupported puAlgo");
0231
0232 l1tkegalgo_ = std::make_unique<l1ct::PFTkEGAlgoEmulator>(
0233 l1ct::PFTkEGAlgoEmuConfig(iConfig.getParameter<edm::ParameterSet>("tkEgAlgoParameters")));
0234
0235 l1tkegsorter_ =
0236 std::make_unique<l1ct::PFTkEGSorterEmulator>(iConfig.getParameter<edm::ParameterSet>("tkEgSorterParameters"));
0237
0238 if (l1tkegalgo_->writeEgSta())
0239 produces<BXVector<l1t::EGamma>>("L1Eg");
0240 produces<l1t::TkElectronCollection>("L1TkEle");
0241 produces<l1t::TkElectronRegionalOutput>("L1TkElePerBoard");
0242 produces<l1t::TkEmCollection>("L1TkEm");
0243 produces<l1t::TkEmRegionalOutput>("L1TkEmPerBoard");
0244
0245 emuTkVtx_ = iConfig.getParameter<bool>("vtxCollectionEmulation");
0246 if (emuTkVtx_) {
0247 tkVtxEmu_ = consumes<std::vector<l1t::VertexWord>>(iConfig.getParameter<edm::InputTag>("vtxCollection"));
0248 } else {
0249 extTkVtx_ = consumes<std::vector<l1t::Vertex>>(iConfig.getParameter<edm::InputTag>("vtxCollection"));
0250 }
0251 nVtx_ = iConfig.getParameter<int>("nVtx");
0252
0253 const char *iprefix[4] = {"totNReg", "maxNReg", "totNSec", "maxNSec"};
0254 for (int i = 0; i <= l1muType; ++i) {
0255 for (int ip = 0; ip < 4; ++ip) {
0256 produces<unsigned int>(std::string(iprefix[ip]) + inputTypeName[i]);
0257 }
0258 produces<std::vector<unsigned>>(std::string("vecNReg") + inputTypeName[i]);
0259 produces<std::vector<unsigned>>(std::string("vecNSec") + inputTypeName[i]);
0260 }
0261 const char *oprefix[4] = {"totNPF", "maxNPF", "totNPuppi", "maxNPuppi"};
0262 for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) {
0263 for (int ip = 0; ip < 4; ++ip) {
0264 produces<unsigned int>(std::string(oprefix[ip]) + l1ct::OutputRegion::objTypeName[i]);
0265 }
0266 produces<std::vector<unsigned>>(std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]);
0267 produces<std::vector<unsigned>>(std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]);
0268 }
0269
0270 initSectorsAndRegions(iConfig);
0271 }
0272
0273 L1TCorrelatorLayer1Producer::~L1TCorrelatorLayer1Producer() {}
0274
0275 void L1TCorrelatorLayer1Producer::beginStream(edm::StreamID id) {
0276 if (!regionDumpName_.empty()) {
0277 if (id == 0) {
0278 fRegionDump_.open(regionDumpName_.c_str(), std::ios::out | std::ios::binary);
0279 } else {
0280 edm::LogWarning("L1TCorrelatorLayer1Producer")
0281 << "Job running with multiple streams, but dump file will have only events on stream zero.";
0282 }
0283 }
0284 if (!patternWriterConfigs_.empty()) {
0285 if (id == 0) {
0286 for (const auto &pset : patternWriterConfigs_) {
0287 patternWriters_.emplace_back(std::make_unique<L1TCorrelatorLayer1PatternFileWriter>(pset, event_));
0288 }
0289 } else {
0290 edm::LogWarning("L1TCorrelatorLayer1Producer")
0291 << "Job running with multiple streams, but pattern files will be written only on stream zero.";
0292 }
0293 }
0294 }
0295
0296 void L1TCorrelatorLayer1Producer::endStream() {
0297 for (auto &writer : patternWriters_) {
0298 writer->flush();
0299 }
0300 }
0301
0302
0303 void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0304
0305 initEvent(iEvent);
0306
0307
0308 if (hasTracks_) {
0309 edm::Handle<l1t::PFTrackCollection> htracks;
0310 iEvent.getByToken(tkCands_, htracks);
0311 const auto &tracks = *htracks;
0312 for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) {
0313 const auto &tk = tracks[itk];
0314
0315 if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_)
0316 continue;
0317 if (tk.pt() > trkPt_) {
0318 addTrack(tk, l1t::PFTrackRef(htracks, itk));
0319 }
0320 }
0321 }
0322
0323
0324 edm::Handle<l1t::SAMuonCollection> muons;
0325 iEvent.getByToken(muCands_, muons);
0326 for (unsigned int i = 0, n = muons->size(); i < n; ++i) {
0327 const l1t::SAMuon &mu = (*muons)[i];
0328 if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_)
0329 continue;
0330 addMuon(mu, l1t::PFCandidate::MuonRef(muons, i));
0331 }
0332
0333 edm::Handle<l1t::PFClusterCollection> caloHandle;
0334 for (const auto &tag : emCands_) {
0335 iEvent.getByToken(tag, caloHandle);
0336 const auto &calos = *caloHandle;
0337 for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
0338 const auto &calo = calos[ic];
0339 if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_)
0340 continue;
0341 if (calo.pt() > emPtCut_)
0342 addEmCalo(calo, l1t::PFClusterRef(caloHandle, ic));
0343 }
0344 }
0345 for (const auto &tag : hadCands_) {
0346 iEvent.getByToken(tag, caloHandle);
0347 const auto &calos = *caloHandle;
0348 for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
0349 const auto &calo = calos[ic];
0350 if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_)
0351 continue;
0352 if (calo.pt() > hadPtCut_)
0353 addHadCalo(calo, l1t::PFClusterRef(caloHandle, ic));
0354 }
0355 }
0356
0357 regionizer_->run(event_.decoded, event_.pfinputs);
0358
0359
0360 iEvent.put(fetchEmCalo(), "EmCalo");
0361 iEvent.put(fetchHadCalo(), "Calo");
0362 iEvent.put(fetchTracks(), "TK");
0363
0364
0365 std::vector<float> z0s;
0366 std::vector<std::pair<float, float>> ptsums;
0367 float z0 = 0;
0368 double ptsum = 0;
0369 l1t::VertexWord pvwd;
0370
0371 if (emuTkVtx_) {
0372 edm::Handle<std::vector<l1t::VertexWord>> vtxEmuHandle;
0373 iEvent.getByToken(tkVtxEmu_, vtxEmuHandle);
0374 for (const auto &vtx : *vtxEmuHandle) {
0375 ptsums.push_back(std::pair<float, float>(vtx.pt(), vtx.z0()));
0376 if (ptsum == 0 || vtx.pt() > ptsum) {
0377 ptsum = vtx.pt();
0378 pvwd = vtx;
0379 }
0380 }
0381 } else {
0382 edm::Handle<std::vector<l1t::Vertex>> vtxHandle;
0383 iEvent.getByToken(extTkVtx_, vtxHandle);
0384 for (const auto &vtx : *vtxHandle) {
0385 ptsums.push_back(std::pair<float, float>(vtx.pt(), vtx.z0()));
0386 if (ptsum == 0 || vtx.pt() > ptsum) {
0387 ptsum = vtx.pt();
0388 z0 = vtx.z0();
0389 }
0390 }
0391 pvwd = l1t::VertexWord(1, z0, 1, ptsum, 1, 1, 1);
0392 }
0393 l1ct::PVObjEmu hwpv;
0394 hwpv.hwZ0 = l1ct::Scales::makeZ0(pvwd.z0());
0395 event_.pvs.push_back(hwpv);
0396 event_.pvs_emu.push_back(pvwd.vertexWord());
0397
0398 if (nVtx_ > 1) {
0399 std::stable_sort(ptsums.begin(), ptsums.end(), [](const auto &a, const auto &b) { return a.first > b.first; });
0400 for (int i0 = 0; i0 < std::min(int(ptsums.size()), int(nVtx_)); i0++) {
0401 z0s.push_back(ptsums[i0].second);
0402 }
0403 for (unsigned int i = 1; i < z0s.size(); ++i) {
0404 l1ct::PVObjEmu hwpv;
0405 hwpv.hwZ0 = l1ct::Scales::makeZ0(z0s[i]);
0406 event_.pvs.push_back(hwpv);
0407 }
0408 }
0409
0410 #if 0
0411 iEvent.put(l1regions_.fetchTracks(0.0, true), "TKVtx");
0412 #endif
0413
0414
0415 event_.out.resize(event_.pfinputs.size());
0416 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0417 l1pfalgo_->run(event_.pfinputs[ir], event_.out[ir]);
0418 l1pfalgo_->mergeNeutrals(event_.out[ir]);
0419 l1tkegalgo_->run(event_.pfinputs[ir], event_.out[ir]);
0420 l1tkegalgo_->runIso(event_.pfinputs[ir], event_.pvs, event_.out[ir]);
0421 }
0422
0423
0424 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0425 l1pualgo_->run(event_.pfinputs[ir], event_.pvs, event_.out[ir]);
0426
0427 }
0428
0429
0430
0431 std::vector<edm::Ref<BXVector<l1t::EGamma>>> egsta_refs;
0432 if (l1tkegalgo_->writeEgSta()) {
0433 putEgStaObjects(iEvent, "L1Eg", egsta_refs);
0434 }
0435
0436
0437 for (auto &board : event_.board_out) {
0438 l1tkegsorter_->run(event_.pfinputs, event_.out, board.region_index, board.egphoton);
0439 l1tkegsorter_->run(event_.pfinputs, event_.out, board.region_index, board.egelectron);
0440 }
0441
0442
0443 iEvent.put(fetchPF(), "PF");
0444
0445
0446 putPuppi(iEvent);
0447
0448
0449 putEgObjects(iEvent, l1tkegalgo_->writeEgSta(), egsta_refs, "L1TkEm", "L1TkEmPerBoard", "L1TkEle", "L1TkElePerBoard");
0450
0451
0452 for (int i = 0; i <= l1muType; ++i) {
0453 auto vecInputs = vecSecInput(InputType(i));
0454 auto tm = totAndMax(*vecInputs);
0455 addUInt(tm.first, std::string("totNSec") + inputTypeName[i], iEvent);
0456 addUInt(tm.second, std::string("maxNSec") + inputTypeName[i], iEvent);
0457 iEvent.put(std::move(vecInputs), std::string("vecNSec") + inputTypeName[i]);
0458 }
0459 for (int i = 0; i <= l1muType; ++i) {
0460 auto vecInputs = vecRegInput(InputType(i));
0461 auto tm = totAndMax(*vecInputs);
0462 addUInt(tm.first, std::string("totNReg") + inputTypeName[i], iEvent);
0463 addUInt(tm.second, std::string("maxNReg") + inputTypeName[i], iEvent);
0464 iEvent.put(std::move(vecInputs), std::string("vecNReg") + inputTypeName[i]);
0465 }
0466 for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) {
0467 auto vecPF = vecOutput(OutputType(i), false);
0468 auto tmPF = totAndMax(*vecPF);
0469 addUInt(tmPF.first, std::string("totNPF") + l1ct::OutputRegion::objTypeName[i], iEvent);
0470 addUInt(tmPF.second, std::string("maxNPF") + l1ct::OutputRegion::objTypeName[i], iEvent);
0471 iEvent.put(std::move(vecPF), std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]);
0472 auto vecPuppi = vecOutput(OutputType(i), true);
0473 auto tmPuppi = totAndMax(*vecPuppi);
0474 addUInt(tmPuppi.first, std::string("totNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent);
0475 addUInt(tmPuppi.second, std::string("maxNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent);
0476 iEvent.put(std::move(vecPuppi), std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]);
0477 }
0478
0479 if (fRegionDump_.is_open()) {
0480 event_.write(fRegionDump_);
0481 }
0482 for (auto &writer : patternWriters_) {
0483 writer->write(event_);
0484 }
0485
0486
0487 event_.clear();
0488 }
0489
0490 void L1TCorrelatorLayer1Producer::addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent) {
0491 iEvent.put(std::make_unique<unsigned>(value), iLabel);
0492 }
0493
0494 void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet &iConfig) {
0495
0496 unsigned int TF_phiSlices = 9;
0497 float TF_phiWidth = 2 * M_PI / TF_phiSlices;
0498 event_.decoded.track.clear();
0499 for (unsigned int ieta = 0, neta = 2; ieta < neta; ++ieta) {
0500 for (unsigned int iphi = 0; iphi < TF_phiSlices; ++iphi) {
0501 float phiCenter = reco::reduceRange(iphi * TF_phiWidth);
0502 event_.decoded.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth);
0503 event_.raw.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth);
0504 }
0505 }
0506
0507 event_.decoded.emcalo.clear();
0508 event_.decoded.hadcalo.clear();
0509 event_.raw.hgcalcluster.clear();
0510
0511 for (const edm::ParameterSet &preg : iConfig.getParameter<std::vector<edm::ParameterSet>>("caloSectors")) {
0512 std::vector<double> etaBoundaries = preg.getParameter<std::vector<double>>("etaBoundaries");
0513 if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end()))
0514 throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n");
0515 unsigned int phiSlices = preg.getParameter<uint32_t>("phiSlices");
0516 float phiWidth = 2 * M_PI / phiSlices;
0517 if (phiWidth > 2 * l1ct::Scales::maxAbsPhi())
0518 throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type");
0519 double phiZero = preg.getParameter<double>("phiZero");
0520 for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) {
0521 float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta];
0522 if (etaWidth > 2 * l1ct::Scales::maxAbsEta())
0523 throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type");
0524 for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) {
0525 float phiCenter = reco::reduceRange(iphi * phiWidth + phiZero);
0526 event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0527 event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0528 event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0529 }
0530 }
0531 }
0532
0533 event_.decoded.muon.region = l1ct::PFRegionEmu(0., 0.);
0534 event_.raw.muon.region = l1ct::PFRegionEmu(0., 0.);
0535
0536 event_.pfinputs.clear();
0537 for (const edm::ParameterSet &preg : iConfig.getParameter<std::vector<edm::ParameterSet>>("regions")) {
0538 std::vector<double> etaBoundaries = preg.getParameter<std::vector<double>>("etaBoundaries");
0539 if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end()))
0540 throw cms::Exception("Configuration", "regions.etaBoundaries not sorted\n");
0541 unsigned int phiSlices = preg.getParameter<uint32_t>("phiSlices");
0542 float etaExtra = preg.getParameter<double>("etaExtra");
0543 float phiExtra = preg.getParameter<double>("phiExtra");
0544 float phiWidth = 2 * M_PI / phiSlices;
0545 for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) {
0546 for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) {
0547 float phiCenter = reco::reduceRange(iphi * phiWidth);
0548 event_.pfinputs.emplace_back(
0549 etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth, etaExtra, phiExtra);
0550 }
0551 }
0552 }
0553
0554 event_.board_out.clear();
0555 const std::vector<edm::ParameterSet> &board_params = iConfig.getParameter<std::vector<edm::ParameterSet>>("boards");
0556 event_.board_out.resize(board_params.size());
0557 for (unsigned int bidx = 0; bidx < board_params.size(); bidx++) {
0558 event_.board_out[bidx].region_index = board_params[bidx].getParameter<std::vector<unsigned int>>("regions");
0559 float etaBoard = 0.;
0560 float phiBoard = 0.;
0561 for (auto ridx : event_.board_out[bidx].region_index) {
0562 etaBoard += event_.pfinputs[ridx].region.floatEtaCenter();
0563 phiBoard += event_.pfinputs[ridx].region.floatPhiCenter();
0564 }
0565 event_.board_out[bidx].eta = etaBoard / event_.board_out[bidx].region_index.size();
0566 event_.board_out[bidx].phi = phiBoard / event_.board_out[bidx].region_index.size();
0567 }
0568 }
0569
0570 void L1TCorrelatorLayer1Producer::initEvent(const edm::Event &iEvent) {
0571 event_.clear();
0572 event_.run = iEvent.id().run();
0573 event_.lumi = iEvent.id().luminosityBlock();
0574 event_.event = iEvent.id().event();
0575 clusterRefMap_.clear();
0576 trackRefMap_.clear();
0577 muonRefMap_.clear();
0578 }
0579
0580 void L1TCorrelatorLayer1Producer::addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref) {
0581 auto &rawsectors = event_.raw.track;
0582 auto §ors = event_.decoded.track;
0583 assert(sectors.size() == 18 && rawsectors.size() == 18);
0584 int isec = t.track()->phiSector() + (t.eta() >= 0 ? 9 : 0);
0585 rawsectors[isec].obj.push_back(t.trackWord().getTrackWord());
0586 addDecodedTrack(sectors[isec], t);
0587 trackRefMap_[&t] = ref;
0588 }
0589 void L1TCorrelatorLayer1Producer::addMuon(const l1t::SAMuon &mu, l1t::PFCandidate::MuonRef ref) {
0590 event_.raw.muon.obj.emplace_back(mu.word());
0591 addDecodedMuon(event_.decoded.muon, mu);
0592 muonRefMap_[&mu] = ref;
0593 }
0594 void L1TCorrelatorLayer1Producer::addHadCalo(const l1t::PFCluster &c, l1t::PFClusterRef ref) {
0595 int sidx = 0;
0596 for (auto &sec : event_.decoded.hadcalo) {
0597 if (sec.region.contains(c.eta(), c.phi())) {
0598 addDecodedHadCalo(sec, c);
0599 if (writeRawHgcalCluster_)
0600 addRawHgcalCluster(event_.raw.hgcalcluster[sidx], c);
0601 }
0602 sidx++;
0603 }
0604 clusterRefMap_[&c] = ref;
0605 }
0606 void L1TCorrelatorLayer1Producer::addEmCalo(const l1t::PFCluster &c, l1t::PFClusterRef ref) {
0607 for (auto &sec : event_.decoded.emcalo) {
0608 if (sec.region.contains(c.eta(), c.phi())) {
0609 addDecodedEmCalo(sec, c);
0610 }
0611 }
0612 clusterRefMap_[&c] = ref;
0613 }
0614
0615 void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector<l1ct::TkObjEmu> &sec, const l1t::PFTrack &t) {
0616 std::pair<l1ct::TkObjEmu, bool> tkAndSel;
0617 if (trackInput_) {
0618 tkAndSel = trackInput_->decodeTrack(t.trackWord().getTrackWord(), sec.region);
0619 } else {
0620 tkAndSel.first.hwPt = l1ct::Scales::makePtFromFloat(t.pt());
0621 tkAndSel.first.hwEta =
0622 l1ct::Scales::makeGlbEta(t.caloEta()) -
0623 sec.region.hwEtaCenter;
0624 tkAndSel.first.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(t.caloPhi()));
0625 tkAndSel.first.hwCharge = t.charge() > 0;
0626 tkAndSel.first.hwQuality = t.quality();
0627 tkAndSel.first.hwDEta = l1ct::Scales::makeEta(t.eta() - t.caloEta());
0628 tkAndSel.first.hwDPhi = l1ct::Scales::makePhi(std::abs(reco::deltaPhi(t.phi(), t.caloPhi())));
0629 tkAndSel.first.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z());
0630 tkAndSel.first.hwDxy = 0;
0631 tkAndSel.second = t.quality() > 0;
0632 }
0633
0634 tkAndSel.first.hwChi2 = round(t.chi2() * 10);
0635 tkAndSel.first.hwStubs = t.nStubs();
0636 tkAndSel.first.simPt = t.pt();
0637 tkAndSel.first.simCaloEta = t.caloEta();
0638 tkAndSel.first.simCaloPhi = t.caloPhi();
0639 tkAndSel.first.simVtxEta = t.eta();
0640 tkAndSel.first.simVtxPhi = t.phi();
0641 tkAndSel.first.simZ0 = t.vertex().Z();
0642 tkAndSel.first.simD0 = t.vertex().Rho();
0643 tkAndSel.first.src = &t;
0644
0645
0646 if (!tkAndSel.second)
0647 tkAndSel.first.hwPt = 0;
0648 sec.obj.push_back(tkAndSel.first);
0649 }
0650
0651 void L1TCorrelatorLayer1Producer::addDecodedMuon(l1ct::DetectorSector<l1ct::MuObjEmu> &sec, const l1t::SAMuon &t) {
0652 l1ct::MuObjEmu mu;
0653 if (muonInput_) {
0654 mu = muonInput_->decode(t.word());
0655 } else {
0656 mu.hwPt = l1ct::Scales::makePtFromFloat(t.pt());
0657 mu.hwEta = l1ct::Scales::makeGlbEta(t.eta());
0658 mu.hwPhi = l1ct::Scales::makeGlbPhi(t.phi());
0659 mu.hwCharge = !t.hwCharge();
0660 mu.hwQuality = t.hwQual() / 2;
0661 mu.hwDEta = 0;
0662 mu.hwDPhi = 0;
0663 mu.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z());
0664 mu.hwDxy = 0;
0665 }
0666 mu.src = &t;
0667 sec.obj.push_back(mu);
0668 }
0669
0670 void L1TCorrelatorLayer1Producer::addDecodedHadCalo(l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec,
0671 const l1t::PFCluster &c) {
0672 l1ct::HadCaloObjEmu calo;
0673 calo.hwPt = l1ct::Scales::makePtFromFloat(c.pt());
0674 calo.hwEta = l1ct::Scales::makeGlbEta(c.eta()) -
0675 sec.region.hwEtaCenter;
0676 calo.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(c.phi()));
0677 calo.hwEmPt = l1ct::Scales::makePtFromFloat(c.emEt());
0678 calo.hwEmID = c.hwEmID();
0679 calo.src = &c;
0680 sec.obj.push_back(calo);
0681 }
0682
0683 void L1TCorrelatorLayer1Producer::addRawHgcalCluster(l1ct::DetectorSector<ap_uint<256>> &sec, const l1t::PFCluster &c) {
0684 ap_uint<256> cwrd = 0;
0685 ap_uint<14> w_pt = round(c.pt() / 0.25);
0686 ap_uint<14> w_empt = round(c.emEt() / 0.25);
0687 constexpr float ETAPHI_LSB = M_PI / 720;
0688 ap_int<9> w_eta = round(sec.region.localEta(c.eta()) / ETAPHI_LSB);
0689 ap_int<9> w_phi = round(sec.region.localPhi(c.phi()) / ETAPHI_LSB);
0690 ap_uint<10> w_qual = c.hwQual();
0691
0692 cwrd(13, 0) = w_pt;
0693 cwrd(27, 14) = w_empt;
0694 cwrd(72, 64) = w_eta;
0695 cwrd(81, 73) = w_phi;
0696 cwrd(115, 106) = w_qual;
0697
0698 sec.obj.push_back(cwrd);
0699 }
0700
0701 void L1TCorrelatorLayer1Producer::addDecodedEmCalo(l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec,
0702 const l1t::PFCluster &c) {
0703 l1ct::EmCaloObjEmu calo;
0704 calo.hwPt = l1ct::Scales::makePtFromFloat(c.pt());
0705 calo.hwEta = l1ct::Scales::makeGlbEta(c.eta()) -
0706 sec.region.hwEtaCenter;
0707 calo.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(c.phi()));
0708 calo.hwPtErr = l1ct::Scales::makePtFromFloat(c.ptError());
0709 calo.hwEmID = c.hwEmID();
0710 calo.src = &c;
0711 sec.obj.push_back(calo);
0712 }
0713
0714 template <typename T>
0715 void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, const T &p) const {
0716 if (p.srcCluster) {
0717 auto match = clusterRefMap_.find(p.srcCluster);
0718 if (match == clusterRefMap_.end()) {
0719 throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt "
0720 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
0721 }
0722 pf.setPFCluster(match->second);
0723 }
0724 if (p.srcTrack) {
0725 auto match = trackRefMap_.find(p.srcTrack);
0726 if (match == trackRefMap_.end()) {
0727 throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.intId() << " pt "
0728 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
0729 }
0730 pf.setPFTrack(match->second);
0731 }
0732 if (p.srcMu) {
0733 auto match = muonRefMap_.find(p.srcMu);
0734 if (match == muonRefMap_.end()) {
0735 throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.intId() << " pt "
0736 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
0737 }
0738 pf.setMuon(match->second);
0739 }
0740 }
0741
0742 template <>
0743 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::PFNeutralObjEmu>(l1t::PFCandidate &pf,
0744 const l1ct::PFNeutralObjEmu &p) const {
0745 if (p.srcCluster) {
0746 auto match = clusterRefMap_.find(p.srcCluster);
0747 if (match == clusterRefMap_.end()) {
0748 throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt "
0749 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
0750 }
0751 pf.setPFCluster(match->second);
0752 }
0753 }
0754
0755 template <>
0756 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::HadCaloObjEmu>(l1t::PFCandidate &pf,
0757 const l1ct::HadCaloObjEmu &p) const {
0758 if (p.src) {
0759 auto match = clusterRefMap_.find(p.src);
0760 if (match == clusterRefMap_.end()) {
0761 throw cms::Exception("CorruptData") << "Invalid cluster pointer in hadcalo candidate pt " << p.floatPt()
0762 << " eta " << p.floatEta() << " phi " << p.floatPhi();
0763 }
0764 pf.setPFCluster(match->second);
0765 }
0766 }
0767
0768 template <>
0769 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::EmCaloObjEmu>(l1t::PFCandidate &pf,
0770 const l1ct::EmCaloObjEmu &p) const {
0771 if (p.src) {
0772 auto match = clusterRefMap_.find(p.src);
0773 if (match == clusterRefMap_.end()) {
0774 throw cms::Exception("CorruptData") << "Invalid cluster pointer in emcalo candidate pt " << p.floatPt()
0775 << " eta " << p.floatEta() << " phi " << p.floatPhi();
0776 }
0777 pf.setPFCluster(match->second);
0778 }
0779 }
0780
0781 template <>
0782 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::TkObjEmu>(l1t::PFCandidate &pf, const l1ct::TkObjEmu &p) const {
0783 if (p.src) {
0784 auto match = trackRefMap_.find(p.src);
0785 if (match == trackRefMap_.end()) {
0786 throw cms::Exception("CorruptData") << "Invalid track pointer in track candidate pt " << p.floatPt() << " eta "
0787 << p.floatEta() << " phi " << p.floatPhi();
0788 }
0789 pf.setPFTrack(match->second);
0790 }
0791 }
0792
0793 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchHadCalo() const {
0794 auto ret = std::make_unique<l1t::PFCandidateCollection>();
0795 for (const auto &r : event_.pfinputs) {
0796 const auto ® = r.region;
0797 for (const auto &p : r.hadcalo) {
0798 if (p.hwPt == 0 || !reg.isFiducial(p))
0799 continue;
0800 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
0801 l1t::PFCandidate::ParticleType type = p.hwIsEM() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
0802 ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
0803 ret->back().setHwEmID(p.hwEmID);
0804 setRefs_(ret->back(), p);
0805 }
0806 }
0807 return ret;
0808 }
0809 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchEmCalo() const {
0810 auto ret = std::make_unique<l1t::PFCandidateCollection>();
0811 for (const auto &r : event_.pfinputs) {
0812 const auto ® = r.region;
0813 for (const auto &p : r.emcalo) {
0814 if (p.hwPt == 0 || !reg.isFiducial(p))
0815 continue;
0816 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
0817 ret->emplace_back(l1t::PFCandidate::Photon, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
0818 ret->back().setHwEmID(p.hwEmID);
0819 setRefs_(ret->back(), p);
0820 }
0821 }
0822 return ret;
0823 }
0824 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchTracks() const {
0825 auto ret = std::make_unique<l1t::PFCandidateCollection>();
0826 for (const auto &r : event_.pfinputs) {
0827 const auto ® = r.region;
0828 for (const auto &p : r.track) {
0829 if (p.hwPt == 0 || !reg.isFiducial(p))
0830 continue;
0831 reco::Particle::PolarLorentzVector p4(
0832 p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f);
0833 ret->emplace_back(l1t::PFCandidate::ChargedHadron, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi());
0834 setRefs_(ret->back(), p);
0835 }
0836 }
0837 return ret;
0838 }
0839
0840 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchPF() const {
0841 auto ret = std::make_unique<l1t::PFCandidateCollection>();
0842 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0843 const auto ® = event_.pfinputs[ir].region;
0844 for (const auto &p : event_.out[ir].pfcharged) {
0845 if (p.hwPt == 0 || !reg.isFiducial(p))
0846 continue;
0847 reco::Particle::PolarLorentzVector p4(
0848 p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f);
0849 l1t::PFCandidate::ParticleType type = l1t::PFCandidate::ChargedHadron;
0850 if (p.hwId.isMuon())
0851 type = l1t::PFCandidate::Muon;
0852 else if (p.hwId.isElectron())
0853 type = l1t::PFCandidate::Electron;
0854 ret->emplace_back(type, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi());
0855 ret->back().setZ0(p.floatZ0());
0856 ret->back().setDxy(p.floatDxy());
0857 ret->back().setHwZ0(p.hwZ0);
0858 ret->back().setHwDxy(p.hwDxy);
0859 ret->back().setHwTkQuality(p.hwTkQuality);
0860 setRefs_(ret->back(), p);
0861 }
0862 for (const auto &p : event_.out[ir].pfneutral) {
0863 if (p.hwPt == 0 || !reg.isFiducial(p))
0864 continue;
0865 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
0866 l1t::PFCandidate::ParticleType type =
0867 p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
0868 ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
0869 ret->back().setHwEmID(p.hwEmID);
0870 setRefs_(ret->back(), p);
0871 }
0872 }
0873 return ret;
0874 }
0875
0876 void L1TCorrelatorLayer1Producer::putPuppi(edm::Event &iEvent) const {
0877 auto refprod = iEvent.getRefBeforePut<l1t::PFCandidateCollection>("Puppi");
0878 auto coll = std::make_unique<l1t::PFCandidateCollection>();
0879 auto reg = std::make_unique<l1t::PFCandidateRegionalOutput>(refprod);
0880 std::vector<int> nobj;
0881 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0882 nobj.clear();
0883 for (const auto &p : event_.out[ir].puppi) {
0884 if (p.hwPt == 0)
0885 continue;
0886
0887 l1t::PFCandidate::ParticleType type;
0888 float mass = 0.13f;
0889 if (p.hwId.charged()) {
0890 if (p.hwId.isMuon()) {
0891 type = l1t::PFCandidate::Muon;
0892 mass = 0.105;
0893 } else if (p.hwId.isElectron()) {
0894 type = l1t::PFCandidate::Electron;
0895 mass = 0.005;
0896 } else
0897 type = l1t::PFCandidate::ChargedHadron;
0898 } else {
0899 type = p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
0900 mass = p.hwId.isPhoton() ? 0.0 : 0.5;
0901 }
0902 reco::Particle::PolarLorentzVector p4(p.floatPt(), p.floatEta(), p.floatPhi(), mass);
0903 coll->emplace_back(type, p.intCharge(), p4, p.floatPuppiW(), p.intPt(), p.intEta(), p.intPhi());
0904 if (p.hwId.charged()) {
0905 coll->back().setZ0(p.floatZ0());
0906 coll->back().setDxy(p.floatDxy());
0907 coll->back().setHwZ0(p.hwZ0());
0908 coll->back().setHwDxy(p.hwDxy());
0909 coll->back().setHwTkQuality(p.hwTkQuality());
0910 } else {
0911 coll->back().setHwPuppiWeight(p.hwPuppiW());
0912 coll->back().setHwEmID(p.hwEmID());
0913 }
0914 coll->back().setEncodedPuppi64(p.pack().to_uint64());
0915 setRefs_(coll->back(), p);
0916 nobj.push_back(coll->size() - 1);
0917 }
0918 reg->addRegion(nobj, event_.pfinputs[ir].region.floatEtaCenter(), event_.pfinputs[ir].region.floatPhiCenter());
0919 }
0920 iEvent.put(std::move(coll), "Puppi");
0921 iEvent.put(std::move(reg), "PuppiRegional");
0922 }
0923
0924
0925
0926 void L1TCorrelatorLayer1Producer::putEgStaObjects(edm::Event &iEvent,
0927 const std::string &egLablel,
0928 std::vector<edm::Ref<BXVector<l1t::EGamma>>> &egsta_refs) {
0929 auto egs = std::make_unique<BXVector<l1t::EGamma>>();
0930 edm::RefProd<BXVector<l1t::EGamma>> ref_egs = iEvent.getRefBeforePut<BXVector<l1t::EGamma>>(egLablel);
0931
0932 edm::Ref<BXVector<l1t::EGamma>>::key_type idx = 0;
0933
0934
0935 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0936 const auto ® = event_.pfinputs[ir].region;
0937
0938 std::vector<unsigned int> ref_pos(event_.out[ir].egsta.size());
0939
0940
0941 for (unsigned int ieg = 0, neg = event_.out[ir].egsta.size(); ieg < neg; ++ieg) {
0942 const auto &p = event_.out[ir].egsta[ieg];
0943 if (p.hwPt == 0 || !reg.isFiducial(p))
0944 continue;
0945 l1t::EGamma eg(
0946 reco::Candidate::PolarLorentzVector(p.floatPt(), reg.floatGlbEta(p.hwEta), reg.floatGlbPhi(p.hwPhi), 0.));
0947 eg.setHwQual(p.hwQual);
0948 egs->push_back(0, eg);
0949 egsta_refs.push_back(edm::Ref<BXVector<l1t::EGamma>>(ref_egs, idx++));
0950 ref_pos[ieg] = egsta_refs.size() - 1;
0951 }
0952
0953 for (auto &egiso : event_.out[ir].egphoton) {
0954 if (egiso.hwPt == 0)
0955 continue;
0956 egiso.sta_idx = ref_pos[egiso.sta_idx];
0957 }
0958
0959 for (auto &egele : event_.out[ir].egelectron) {
0960 if (egele.hwPt == 0)
0961 continue;
0962 egele.sta_idx = ref_pos[egele.sta_idx];
0963 }
0964 }
0965
0966 iEvent.put(std::move(egs), egLablel);
0967 }
0968
0969 void L1TCorrelatorLayer1Producer::putEgObjects(edm::Event &iEvent,
0970 const bool writeEgSta,
0971 const std::vector<edm::Ref<BXVector<l1t::EGamma>>> &egsta_refs,
0972 const std::string &tkEmLabel,
0973 const std::string &tkEmPerBoardLabel,
0974 const std::string &tkEleLabel,
0975 const std::string &tkElePerBoardLabel) const {
0976 auto tkems = std::make_unique<l1t::TkEmCollection>();
0977 auto tkemRefProd = iEvent.getRefBeforePut<l1t::TkEmCollection>(tkEmLabel);
0978 auto tkemPerBoard = std::make_unique<l1t::TkEmRegionalOutput>(tkemRefProd);
0979 auto tkeles = std::make_unique<l1t::TkElectronCollection>();
0980 auto tkeleRefProd = iEvent.getRefBeforePut<l1t::TkElectronCollection>(tkEleLabel);
0981 auto tkelePerBoard = std::make_unique<l1t::TkElectronRegionalOutput>(tkeleRefProd);
0982
0983
0984
0985 std::vector<int> nele_obj;
0986 std::vector<int> npho_obj;
0987
0988 for (const auto &board : event_.board_out) {
0989 npho_obj.clear();
0990 for (const auto &egiso : board.egphoton) {
0991 if (egiso.hwPt == 0)
0992 continue;
0993
0994 edm::Ref<BXVector<l1t::EGamma>> ref_egsta;
0995 if (writeEgSta) {
0996 ref_egsta = egsta_refs[egiso.sta_idx];
0997 } else {
0998 auto egptr = egiso.srcCluster->constituentsAndFractions()[0].first;
0999 ref_egsta =
1000 edm::Ref<BXVector<l1t::EGamma>>(egptr.id(), dynamic_cast<const l1t::EGamma *>(egptr.get()), egptr.key());
1001 }
1002
1003 reco::Candidate::PolarLorentzVector mom(egiso.floatPt(), egiso.floatEta(), egiso.floatPhi(), 0.);
1004
1005 l1t::TkEm tkem(reco::Candidate::LorentzVector(mom),
1006 ref_egsta,
1007 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIso),
1008 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIsoPV));
1009 tkem.setHwQual(egiso.hwQual);
1010 tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso));
1011 tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV));
1012 tkem.setEgBinaryWord(egiso.pack());
1013 tkems->push_back(tkem);
1014 npho_obj.push_back(tkems->size() - 1);
1015 }
1016 tkemPerBoard->addRegion(npho_obj, board.eta, board.phi);
1017
1018 nele_obj.clear();
1019 for (const auto &egele : board.egelectron) {
1020 if (egele.hwPt == 0)
1021 continue;
1022
1023 edm::Ref<BXVector<l1t::EGamma>> ref_egsta;
1024 if (writeEgSta) {
1025 ref_egsta = egsta_refs[egele.sta_idx];
1026 } else {
1027 auto egptr = egele.srcCluster->constituentsAndFractions()[0].first;
1028 ref_egsta =
1029 edm::Ref<BXVector<l1t::EGamma>>(egptr.id(), dynamic_cast<const l1t::EGamma *>(egptr.get()), egptr.key());
1030 }
1031
1032 reco::Candidate::PolarLorentzVector mom(egele.floatPt(), egele.floatEta(), egele.floatPhi(), 0.);
1033
1034 l1t::TkElectron tkele(reco::Candidate::LorentzVector(mom),
1035 ref_egsta,
1036 edm::refToPtr(egele.srcTrack->track()),
1037 egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso));
1038 tkele.setHwQual(egele.hwQual);
1039 tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso));
1040 tkele.setEgBinaryWord(egele.pack());
1041 tkeles->push_back(tkele);
1042 nele_obj.push_back(tkeles->size() - 1);
1043 }
1044 tkelePerBoard->addRegion(nele_obj, board.eta, board.phi);
1045 }
1046
1047 iEvent.put(std::move(tkems), tkEmLabel);
1048 iEvent.put(std::move(tkemPerBoard), tkEmPerBoardLabel);
1049 iEvent.put(std::move(tkeles), tkEleLabel);
1050 iEvent.put(std::move(tkelePerBoard), tkElePerBoardLabel);
1051 }
1052
1053 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecSecInput(InputType t) const {
1054 auto v = std::make_unique<std::vector<unsigned>>();
1055 {
1056 switch (t) {
1057 case caloType:
1058 for (const auto &s : event_.decoded.hadcalo)
1059 v->push_back(s.size());
1060 break;
1061 case emcaloType:
1062 for (const auto &s : event_.decoded.emcalo)
1063 v->push_back(s.size());
1064 break;
1065 case trackType:
1066 for (const auto &s : event_.decoded.track)
1067 v->push_back(s.size());
1068 break;
1069 case l1muType:
1070 v->push_back(event_.decoded.muon.size());
1071 break;
1072 }
1073 }
1074 return v;
1075 }
1076
1077 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecRegInput(InputType t) const {
1078 auto v = std::make_unique<std::vector<unsigned>>();
1079 for (const auto ® : event_.pfinputs) {
1080 switch (t) {
1081 case caloType:
1082 v->push_back(reg.hadcalo.size());
1083 break;
1084 case emcaloType:
1085 v->push_back(reg.emcalo.size());
1086 break;
1087 case trackType:
1088 v->push_back(reg.track.size());
1089 break;
1090 case l1muType:
1091 v->push_back(reg.muon.size());
1092 break;
1093 }
1094 }
1095 return v;
1096 }
1097
1098 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecOutput(OutputType i, bool usePuppi) const {
1099 auto v = std::make_unique<std::vector<unsigned>>();
1100 for (const auto ® : event_.out) {
1101 v->push_back(reg.nObj(i, usePuppi));
1102 }
1103 return v;
1104 }
1105 std::pair<unsigned int, unsigned int> L1TCorrelatorLayer1Producer::totAndMax(
1106 const std::vector<unsigned> &perRegion) const {
1107 unsigned int ntot = 0, nmax = 0;
1108 for (unsigned ni : perRegion) {
1109 ntot += ni;
1110 nmax = std::max(nmax, ni);
1111 }
1112 return std::make_pair(ntot, nmax);
1113 }
1114
1115 #include "FWCore/Framework/interface/MakerMacros.h"
1116 DEFINE_FWK_MODULE(L1TCorrelatorLayer1Producer);