File indexing completed on 2025-06-20 01:53:34
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 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0015 #include "FWCore/ParameterSet/interface/allowedValues.h"
0016
0017 #include "DataFormats/Common/interface/RefToPtr.h"
0018 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0019 #include "DataFormats/L1TParticleFlow/interface/PFCluster.h"
0020 #include "DataFormats/L1Trigger/interface/Vertex.h"
0021 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0022
0023 #include "DataFormats/Math/interface/deltaR.h"
0024
0025 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h"
0026 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h"
0027 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h"
0028 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h"
0029 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h"
0030 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h"
0031 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h"
0032 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h"
0033 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h"
0034 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h"
0035 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h"
0036 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h"
0037 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h"
0038 #include "L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h"
0039 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h"
0040 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h"
0041 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h"
0042 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h"
0043 #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h"
0044
0045 #include "DataFormats/L1TCorrelator/interface/TkElectron.h"
0046 #include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h"
0047 #include "DataFormats/L1Trigger/interface/EGamma.h"
0048 #include "DataFormats/L1TCorrelator/interface/TkEm.h"
0049 #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h"
0050
0051 #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h"
0052 #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h"
0053
0054 #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h"
0055 #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h"
0056
0057 constexpr unsigned int calomapping[] = {3, 0, 9, 6, 4, 1, 10, 7, 5, 2, 11, 8};
0058
0059
0060
0061
0062
0063 class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> {
0064 public:
0065 explicit L1TCorrelatorLayer1Producer(const edm::ParameterSet &);
0066 ~L1TCorrelatorLayer1Producer() override;
0067
0068 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0069
0070 private:
0071 edm::ParameterSet config_;
0072
0073 bool hasTracks_;
0074 edm::EDGetTokenT<l1t::PFTrackCollection> tkCands_;
0075 float trkPt_;
0076 bool emuTkVtx_;
0077 edm::EDGetTokenT<std::vector<l1t::Vertex>> extTkVtx_;
0078 edm::EDGetTokenT<std::vector<l1t::VertexWord>> tkVtxEmu_;
0079 int nVtx_;
0080
0081 edm::EDGetTokenT<l1t::SAMuonCollection> muCands_;
0082
0083
0084
0085 edm::EDGetTokenT<l1t::PFClusterCollection> hadGCTCands_;
0086 edm::EDGetTokenT<l1t::HGCalMulticlusterBxCollection> hadHGCalCands_;
0087
0088
0089 edm::EDGetTokenT<l1tp2::GCTEmDigiClusterCollection> emGCTRawCands_;
0090 edm::EDGetTokenT<l1tp2::GCTHadDigiClusterCollection> hadGCTRawCands_;
0091
0092 float emPtCut_, hadPtCut_;
0093
0094 l1ct::Event event_;
0095 std::unique_ptr<l1ct::TrackInputEmulator> trackInput_;
0096 std::unique_ptr<l1ct::GMTMuonDecoderEmulator> muonInput_;
0097 std::unique_ptr<l1ct::HgcalClusterDecoderEmulator> hgcalInput_;
0098 std::unique_ptr<l1ct::GctHadClusterDecoderEmulator> gctHadInput_;
0099 std::unique_ptr<l1ct::GctEmClusterDecoderEmulator> gctEmInput_;
0100 std::unique_ptr<l1ct::RegionizerEmulator> regionizer_;
0101 std::unique_ptr<l1ct::PFAlgoEmulatorBase> l1pfalgo_;
0102 std::unique_ptr<l1ct::LinPuppiEmulator> l1pualgo_;
0103 std::unique_ptr<l1ct::PFTkEGAlgoEmulator> l1tkegalgo_;
0104 std::unique_ptr<l1ct::PFTkEGSorterEmulator> l1tkegsorter_;
0105
0106
0107 const std::string regionDumpName_;
0108 std::fstream fRegionDump_;
0109 const edm::VParameterSet patternWriterConfigs_;
0110 std::vector<std::unique_ptr<L1TCorrelatorLayer1PatternFileWriter>> patternWriters_;
0111
0112
0113 float debugEta_, debugPhi_, debugR_;
0114
0115
0116 std::unordered_map<const l1t::L1Candidate *, edm::Ptr<l1t::L1Candidate>> clusterRefMap_;
0117 std::unordered_map<const l1t::PFTrack *, l1t::PFTrackRef> trackRefMap_;
0118 std::unordered_map<const l1t::SAMuon *, l1t::PFCandidate::MuonRef> muonRefMap_;
0119
0120
0121 void beginStream(edm::StreamID) override;
0122 void endStream() override;
0123 void produce(edm::Event &, const edm::EventSetup &) override;
0124 void encodeAndAddHgcalCluster(ap_uint<256> &word,
0125 l1ct::DetectorSector<ap_uint<256>> &sec,
0126 const l1t::HGCalMulticluster &calo) const;
0127 void getDecodedGCTPFCluster(l1ct::HadCaloObjEmu &calo,
0128 l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec,
0129 const l1t::PFCluster &cluster) const;
0130 void addDecodedEmCalo(l1ct::EmCaloObjEmu &decCalo,
0131 const edm::Ptr<l1t::L1Candidate> &caloPtr,
0132 l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec);
0133 void addEmPFCluster(const l1ct::EmCaloObjEmu &decCalo,
0134 const l1ct::PFRegionEmu ®ion,
0135 std::unique_ptr<l1t::PFClusterCollection> &pfClusters) const;
0136 void addDecodedHadCalo(l1ct::HadCaloObjEmu &decCalo,
0137 const edm::Ptr<l1t::L1Candidate> &caloPtr,
0138 l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec);
0139
0140 void addHadPFCluster(const l1ct::HadCaloObjEmu &decCalo,
0141 const l1ct::PFRegionEmu ®ion,
0142 std::unique_ptr<l1t::PFClusterCollection> &pfClusters) const;
0143
0144 void addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent);
0145
0146 void initSectorsAndRegions(const edm::ParameterSet &iConfig);
0147 void initEvent(const edm::Event &e);
0148
0149 void addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref);
0150 void addMuon(const l1t::SAMuon &t, l1t::PFCandidate::MuonRef ref);
0151
0152 void addHGCalHadCalo(const l1t::HGCalMulticluster &calo, const edm::Ptr<l1t::L1Candidate> &caloPtr);
0153
0154 void addGCTHadCalo(const l1t::PFCluster &calo, const edm::Ptr<l1t::L1Candidate> &caloPtr);
0155
0156 void addGCTEmCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, unsigned int linkidx, unsigned int entidx);
0157 void addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, unsigned int linkidx, unsigned int entidx);
0158
0159 void addDecodedTrack(l1ct::DetectorSector<l1ct::TkObjEmu> &sec, const l1t::PFTrack &t);
0160 void addDecodedMuon(l1ct::DetectorSector<l1ct::MuObjEmu> &sec, const l1t::SAMuon &t);
0161 void addDecodedGCTEmCalo(l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec, const l1tp2::GCTEmDigiCluster &digi);
0162 void addDecodedGCTHadCalo(l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec, const l1tp2::GCTHadDigiCluster &digi);
0163
0164 void rawHgcalClusterEncode(ap_uint<256> &cwrd,
0165 const l1ct::DetectorSector<ap_uint<256>> &sec,
0166 const l1t::HGCalMulticluster &c) const;
0167
0168
0169 std::unique_ptr<l1t::PFCandidateCollection> fetchHadCalo() const;
0170 std::unique_ptr<l1t::PFCandidateCollection> fetchEmCalo() const;
0171 std::unique_ptr<l1t::PFCandidateCollection> fetchTracks() const;
0172 std::unique_ptr<l1t::PFCandidateCollection> fetchPF() const;
0173 std::unique_ptr<l1t::PFClusterCollection> fetchDecodedHadCalo() const;
0174 std::unique_ptr<l1t::PFClusterCollection> fetchDecodedEmCalo() const;
0175 std::unique_ptr<l1t::PFTrackCollection> fetchDecodedTracks() const;
0176 void putPuppi(edm::Event &iEvent) const;
0177
0178 void putEgStaObjects(edm::Event &iEvent, const std::string &egLablel) const;
0179 void putEgObjects(edm::Event &iEvent,
0180 const bool writeEgSta,
0181 const std::string &tkEmLabel,
0182 const std::string &tkEmPerBoardLabel,
0183 const std::string &tkEleLabel,
0184 const std::string &tkElePerBoardLabel) const;
0185
0186 template <typename T>
0187 void setRefs_(l1t::PFCandidate &pf, const T &p) const;
0188 template <typename T>
0189 void setRefs_(l1t::PFCluster &pf, const T &p) const;
0190 template <typename Tm, typename Tk, typename To>
0191 auto findRef_(const Tm &map, const Tk *key, const To &obj) const {
0192 auto match = map.find(key);
0193 if (match == map.end()) {
0194 throw cms::Exception("CorruptData") << refExcepMsg_(obj);
0195 }
0196 return match->second;
0197 }
0198 template <typename T>
0199 std::string refExcepMsg_(const T &key) const;
0200
0201 void doVertexings(std::vector<float> &pvdz) const;
0202
0203 enum InputType { caloType = 0, emcaloType = 1, trackType = 2, l1muType = 3 };
0204 static constexpr const char *inputTypeName[l1muType + 1] = {"Calo", "EmCalo", "TK", "Mu"};
0205 std::unique_ptr<std::vector<unsigned>> vecSecInput(InputType i) const;
0206 std::unique_ptr<std::vector<unsigned>> vecRegInput(InputType i) const;
0207 typedef l1ct::OutputRegion::ObjType OutputType;
0208 std::unique_ptr<std::vector<unsigned>> vecOutput(OutputType i, bool usePuppi) const;
0209 std::pair<unsigned int, unsigned int> totAndMax(const std::vector<unsigned> &perRegion) const;
0210
0211
0212 template <typename T>
0213 static edm::ParameterDescription<edm::ParameterSetDescription> getParDesc(const std::string &name) {
0214 return edm::ParameterDescription<edm::ParameterSetDescription>(
0215 name + "Parameters", T::getParameterSetDescription(), true);
0216 }
0217 };
0218
0219
0220
0221
0222 L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet &iConfig)
0223 : config_(iConfig),
0224 hasTracks_(!iConfig.getParameter<edm::InputTag>("tracks").label().empty()),
0225 tkCands_(hasTracks_ ? consumes<l1t::PFTrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"))
0226 : edm::EDGetTokenT<l1t::PFTrackCollection>()),
0227 trkPt_(iConfig.getParameter<double>("trkPtCut")),
0228 muCands_(consumes<l1t::SAMuonCollection>(iConfig.getParameter<edm::InputTag>("muons"))),
0229 emPtCut_(iConfig.getParameter<double>("emPtCut")),
0230 hadPtCut_(iConfig.getParameter<double>("hadPtCut")),
0231 regionizer_(nullptr),
0232 l1pfalgo_(nullptr),
0233 l1pualgo_(nullptr),
0234 l1tkegalgo_(nullptr),
0235 l1tkegsorter_(nullptr),
0236 regionDumpName_(iConfig.getUntrackedParameter<std::string>("dumpFileName")),
0237 patternWriterConfigs_(iConfig.getUntrackedParameter<edm::VParameterSet>("patternWriters")),
0238 debugEta_(iConfig.getUntrackedParameter<double>("debugEta")),
0239 debugPhi_(iConfig.getUntrackedParameter<double>("debugPhi")),
0240 debugR_(iConfig.getUntrackedParameter<double>("debugR")) {
0241 produces<l1t::PFCandidateCollection>("PF");
0242 produces<l1t::PFCandidateCollection>("Puppi");
0243 produces<l1t::PFCandidateRegionalOutput>("PuppiRegional");
0244
0245 produces<l1t::PFCandidateCollection>("EmCalo");
0246 produces<l1t::PFCandidateCollection>("Calo");
0247 produces<l1t::PFCandidateCollection>("TK");
0248 #if 0
0249 produces<l1t::PFCandidateCollection>("TKVtx");
0250 #endif
0251 produces<l1t::PFTrackCollection>("DecodedTK");
0252 produces<l1t::PFClusterCollection>("DecodedEmClusters");
0253 produces<l1t::PFClusterCollection>("DecodedHadClusters");
0254
0255 if (hasTracks_) {
0256 const std::string &tkInAlgo = iConfig.getParameter<std::string>("trackInputConversionAlgo");
0257 if (tkInAlgo == "Emulator") {
0258 trackInput_ = std::make_unique<l1ct::TrackInputEmulator>(
0259 iConfig.getParameter<edm::ParameterSet>("trackInputConversionParameters"));
0260 } else if (tkInAlgo != "Ideal")
0261 throw cms::Exception("Configuration", "Unsupported trackInputConversionAlgo");
0262 }
0263
0264 const std::string &muInAlgo = iConfig.getParameter<std::string>("muonInputConversionAlgo");
0265 if (muInAlgo == "Emulator") {
0266 muonInput_ = std::make_unique<l1ct::GMTMuonDecoderEmulator>(
0267 iConfig.getParameter<edm::ParameterSet>("muonInputConversionParameters"));
0268 } else if (muInAlgo != "Ideal")
0269 throw cms::Exception("Configuration", "Unsupported muonInputConversionAlgo");
0270
0271 const std::string &hgcalInAlgo = iConfig.getParameter<std::string>("hgcalInputConversionAlgo");
0272 const edm::InputTag hadClusters = iConfig.getParameter<edm::InputTag>("hadClusters");
0273 if (!hadClusters.label().empty()) {
0274 if (hgcalInAlgo == "Emulator") {
0275 hadHGCalCands_ = consumes<l1t::HGCalMulticlusterBxCollection>(hadClusters);
0276 hgcalInput_ = std::make_unique<l1ct::HgcalClusterDecoderEmulator>(
0277 iConfig.getParameter<edm::ParameterSet>("hgcalInputConversionParameters"));
0278 } else if (hgcalInAlgo != "None")
0279 throw cms::Exception("Configuration", "Unsupported hgcalInputConversionAlgo");
0280 }
0281 const std::string &gctEmInAlgo = iConfig.getParameter<std::string>("gctEmInputConversionAlgo");
0282 const edm::InputTag emClusters = iConfig.getParameter<edm::InputTag>("emClusters");
0283 if (!emClusters.label().empty()) {
0284 if (gctEmInAlgo == "Emulator") {
0285 gctEmInput_ = std::make_unique<l1ct::GctEmClusterDecoderEmulator>(
0286 iConfig.getParameter<edm::ParameterSet>("gctEmInputConversionParameters"));
0287 emGCTRawCands_ = consumes<l1tp2::GCTEmDigiClusterCollection>(emClusters);
0288 } else if (gctEmInAlgo != "None")
0289 throw cms::Exception("Configuration", "Unsupported gctEmInputConversionAlgo");
0290 }
0291 const std::string &gctHadInAlgo = iConfig.getParameter<std::string>("gctHadInputConversionAlgo");
0292 if (!hadClusters.label().empty()) {
0293 if (gctHadInAlgo == "Emulator") {
0294 gctHadInput_ = std::make_unique<l1ct::GctHadClusterDecoderEmulator>(
0295 iConfig.getParameter<edm::ParameterSet>("gctHadInputConversionParameters"));
0296 hadGCTRawCands_ = consumes<l1tp2::GCTHadDigiClusterCollection>(hadClusters);
0297 } else if (gctHadInAlgo == "Ideal") {
0298 hadGCTCands_ = consumes<l1t::PFClusterCollection>(hadClusters);
0299 } else if (gctHadInAlgo != "None")
0300 throw cms::Exception("Configuration", "Unsupported gctHadInputConversionAlgo");
0301 }
0302
0303 const std::string ®algo = iConfig.getParameter<std::string>("regionizerAlgo");
0304 if (regalgo == "Ideal") {
0305 regionizer_ =
0306 std::make_unique<l1ct::RegionizerEmulator>(iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0307 } else if (regalgo == "Multififo") {
0308 regionizer_ = std::make_unique<l1ct::MultififoRegionizerEmulator>(
0309 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0310 } else if (regalgo == "BufferedFoldedMultififo") {
0311 regionizer_ = std::make_unique<l1ct::BufferedFoldedMultififoRegionizerEmulator>(
0312 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0313 } else if (regalgo == "MultififoBarrel") {
0314 const auto &pset = iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters");
0315 regionizer_ =
0316 std::make_unique<l1ct::MultififoRegionizerEmulator>(pset.getParameter<std::string>("barrelSetup"), pset);
0317 } else if (regalgo == "MiddleBufferMultififo") {
0318 regionizer_ = std::make_unique<l1ct::MiddleBufferMultififoRegionizerEmulator>(
0319 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0320 } else if (regalgo == "TDR") {
0321 regionizer_ = std::make_unique<l1ct::TDRRegionizerEmulator>(
0322 iConfig.getParameter<edm::ParameterSet>("regionizerAlgoParameters"));
0323 } else
0324 throw cms::Exception("Configuration", "Unsupported regionizerAlgo");
0325
0326 const std::string &algo = iConfig.getParameter<std::string>("pfAlgo");
0327 if (algo == "PFAlgo3") {
0328 l1pfalgo_ = std::make_unique<l1ct::PFAlgo3Emulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0329 } else if (algo == "PFAlgo2HGC") {
0330 l1pfalgo_ = std::make_unique<l1ct::PFAlgo2HGCEmulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0331 } else if (algo == "PFAlgoDummy") {
0332 l1pfalgo_ =
0333 std::make_unique<l1ct::PFAlgoDummyEmulator>(iConfig.getParameter<edm::ParameterSet>("pfAlgoParameters"));
0334 } else
0335 throw cms::Exception("Configuration", "Unsupported pfAlgo");
0336
0337 const std::string &pualgo = iConfig.getParameter<std::string>("puAlgo");
0338 if (pualgo == "LinearizedPuppi") {
0339 l1pualgo_ = std::make_unique<l1ct::LinPuppiEmulator>(iConfig.getParameter<edm::ParameterSet>("puAlgoParameters"));
0340 } else
0341 throw cms::Exception("Configuration", "Unsupported puAlgo");
0342
0343 l1tkegalgo_ = std::make_unique<l1ct::PFTkEGAlgoEmulator>(
0344 l1ct::PFTkEGAlgoEmuConfig(iConfig.getParameter<edm::ParameterSet>("tkEgAlgoParameters")));
0345
0346 const std::string &egsortalgo = iConfig.getParameter<std::string>("tkEgSorterAlgo");
0347 if (egsortalgo == "Barrel") {
0348 l1tkegsorter_ = std::make_unique<l1ct::PFTkEGSorterBarrelEmulator>(
0349 iConfig.getParameter<edm::ParameterSet>("tkEgSorterParameters"));
0350 } else if (egsortalgo == "Endcap") {
0351 l1tkegsorter_ =
0352 std::make_unique<l1ct::PFTkEGSorterEmulator>(iConfig.getParameter<edm::ParameterSet>("tkEgSorterParameters"));
0353 } else
0354 throw cms::Exception("Configuration", "Unsupported tkEgSorterAlgo");
0355
0356 if (l1tkegalgo_->writeEgSta())
0357 produces<BXVector<l1t::EGamma>>("L1Eg");
0358 produces<l1t::TkElectronCollection>("L1TkEle");
0359 produces<l1t::TkElectronRegionalOutput>("L1TkElePerBoard");
0360 produces<l1t::TkEmCollection>("L1TkEm");
0361 produces<l1t::TkEmRegionalOutput>("L1TkEmPerBoard");
0362
0363 emuTkVtx_ = iConfig.getParameter<bool>("vtxCollectionEmulation");
0364 if (emuTkVtx_) {
0365 tkVtxEmu_ = consumes<std::vector<l1t::VertexWord>>(iConfig.getParameter<edm::InputTag>("vtxCollection"));
0366 } else {
0367 extTkVtx_ = consumes<std::vector<l1t::Vertex>>(iConfig.getParameter<edm::InputTag>("vtxCollection"));
0368 }
0369 nVtx_ = iConfig.getParameter<int>("nVtx");
0370
0371 const char *iprefix[4] = {"totNReg", "maxNReg", "totNSec", "maxNSec"};
0372 for (int i = 0; i <= l1muType; ++i) {
0373 for (int ip = 0; ip < 4; ++ip) {
0374 produces<unsigned int>(std::string(iprefix[ip]) + inputTypeName[i]);
0375 }
0376 produces<std::vector<unsigned>>(std::string("vecNReg") + inputTypeName[i]);
0377 produces<std::vector<unsigned>>(std::string("vecNSec") + inputTypeName[i]);
0378 }
0379 const char *oprefix[4] = {"totNPF", "maxNPF", "totNPuppi", "maxNPuppi"};
0380 for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) {
0381 for (int ip = 0; ip < 4; ++ip) {
0382 produces<unsigned int>(std::string(oprefix[ip]) + l1ct::OutputRegion::objTypeName[i]);
0383 }
0384 produces<std::vector<unsigned>>(std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]);
0385 produces<std::vector<unsigned>>(std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]);
0386 }
0387
0388 initSectorsAndRegions(iConfig);
0389 }
0390
0391 L1TCorrelatorLayer1Producer::~L1TCorrelatorLayer1Producer() {}
0392
0393 void L1TCorrelatorLayer1Producer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0394 edm::ParameterSetDescription desc;
0395
0396 desc.add<edm::InputTag>("tracks", edm::InputTag(""));
0397 desc.add<edm::InputTag>("muons", edm::InputTag("l1tSAMuonsGmt", "prompt"));
0398 desc.add<edm::InputTag>("emClusters", edm::InputTag(""));
0399 desc.add<edm::InputTag>("hadClusters", edm::InputTag(""));
0400 desc.add<edm::InputTag>("vtxCollection", edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"));
0401 desc.add<bool>("vtxCollectionEmulation", true);
0402 desc.add<double>("emPtCut", 0.0);
0403 desc.add<double>("hadPtCut", 0.0);
0404 desc.add<double>("trkPtCut", 0.0);
0405 desc.add<int32_t>("nVtx");
0406
0407 edm::EmptyGroupDescription emptyGroup;
0408 desc.ifValue(edm::ParameterDescription<std::string>("trackInputConversionAlgo", "Ideal", true),
0409 "Ideal" >> emptyGroup or "Emulator" >> getParDesc<l1ct::TrackInputEmulator>("trackInputConversion"));
0410 desc.ifValue(edm::ParameterDescription<std::string>("muonInputConversionAlgo", "Ideal", true),
0411 "Ideal" >> emptyGroup or "Emulator" >> getParDesc<l1ct::GMTMuonDecoderEmulator>("muonInputConversion"));
0412 desc.ifValue(
0413 edm::ParameterDescription<std::string>("hgcalInputConversionAlgo", "None", true),
0414 "None" >> emptyGroup or "Emulator" >> getParDesc<l1ct::HgcalClusterDecoderEmulator>("hgcalInputConversion"));
0415 desc.ifValue(
0416 edm::ParameterDescription<std::string>("gctEmInputConversionAlgo", "None", true),
0417 "None" >> emptyGroup or "Emulator" >> getParDesc<l1ct::GctEmClusterDecoderEmulator>("gctEmInputConversion"));
0418 desc.ifValue(edm::ParameterDescription<std::string>("gctHadInputConversionAlgo", "None", true),
0419 "Ideal" >> emptyGroup or "None" >> emptyGroup or
0420 "Emulator" >> getParDesc<l1ct::GctHadClusterDecoderEmulator>("gctHadInputConversion"));
0421
0422 auto idealRegPD = getParDesc<l1ct::RegionizerEmulator>("regionizerAlgo");
0423 auto tdrRegPD = getParDesc<l1ct::TDRRegionizerEmulator>("regionizerAlgo");
0424 auto multififoRegPD = getParDesc<l1ct::MultififoRegionizerEmulator>("regionizerAlgo");
0425 auto bfMultififoRegPD = getParDesc<l1ct::BufferedFoldedMultififoRegionizerEmulator>("regionizerAlgo");
0426 auto multififoBarrelRegPD = edm::ParameterDescription<edm::ParameterSetDescription>(
0427 "regionizerAlgoParameters", l1ct::MultififoRegionizerEmulator::getParameterSetDescriptionBarrel(), true);
0428 auto mbMultififoRegPD = getParDesc<l1ct::MiddleBufferMultififoRegionizerEmulator>("regionizerAlgo");
0429 desc.ifValue(edm::ParameterDescription<std::string>("regionizerAlgo", "Ideal", true),
0430 "Ideal" >> idealRegPD or "TDR" >> tdrRegPD or "Multififo" >> multififoRegPD or
0431 "BufferedFoldedMultififo" >> bfMultififoRegPD or "MultififoBarrel" >> multififoBarrelRegPD or
0432 "MiddleBufferMultififo" >> mbMultififoRegPD);
0433
0434 desc.ifValue(edm::ParameterDescription<std::string>("pfAlgo", "PFAlgo3", true),
0435 "PFAlgo3" >> getParDesc<l1ct::PFAlgo3Emulator>("pfAlgo") or
0436 "PFAlgo2HGC" >> getParDesc<l1ct::PFAlgo2HGCEmulator>("pfAlgo") or
0437 "PFAlgoDummy" >> getParDesc<l1ct::PFAlgoDummyEmulator>("pfAlgo"));
0438
0439 desc.ifValue(edm::ParameterDescription<std::string>("puAlgo", "LinearizedPuppi", true),
0440 "LinearizedPuppi" >> getParDesc<l1ct::LinPuppiEmulator>("puAlgo"));
0441
0442 desc.add<edm::ParameterSetDescription>("tkEgAlgoParameters", l1ct::PFTkEGAlgoEmuConfig::getParameterSetDescription());
0443
0444 desc.ifValue(edm::ParameterDescription<std::string>("tkEgSorterAlgo", "Barrel", true),
0445 "Barrel" >> getParDesc<l1ct::PFTkEGSorterBarrelEmulator>("tkEgSorter") or
0446 "Endcap" >> getParDesc<l1ct::PFTkEGSorterEmulator>("tkEgSorter"));
0447
0448 edm::ParameterSetDescription caloSectorPSD;
0449 caloSectorPSD.add<std::vector<double>>("etaBoundaries");
0450 caloSectorPSD.add<uint32_t>("phiSlices", 3);
0451 caloSectorPSD.add<double>("phiZero", 0.);
0452 desc.addVPSet("caloSectors", caloSectorPSD);
0453
0454 edm::ParameterSetDescription regionPSD;
0455 regionPSD.add<std::vector<double>>("etaBoundaries");
0456 regionPSD.add<uint32_t>("phiSlices", 9);
0457 regionPSD.add<double>("etaExtra", 0.25);
0458 regionPSD.add<double>("phiExtra", 0.25);
0459 desc.addVPSet("regions", regionPSD);
0460
0461 edm::ParameterSetDescription boardPSD;
0462 boardPSD.add<std::vector<unsigned int>>("regions");
0463 desc.addVPSet("boards", boardPSD);
0464
0465 desc.addUntracked<std::string>("dumpFileName", "");
0466
0467 desc.addVPSetUntracked(
0468 "patternWriters", L1TCorrelatorLayer1PatternFileWriter::getParameterSetDescription(), edm::VParameterSet());
0469
0470 desc.addUntracked<double>("debugEta", 0.);
0471 desc.addUntracked<double>("debugPhi", 0.);
0472 desc.addUntracked<double>("debugR", -1.);
0473 descriptions.add("l1tCorrelatorLayer1", desc);
0474 }
0475
0476 void L1TCorrelatorLayer1Producer::beginStream(edm::StreamID id) {
0477 if (!regionDumpName_.empty()) {
0478 if (id == 0) {
0479 fRegionDump_.open(regionDumpName_.c_str(), std::ios::out | std::ios::binary);
0480 } else {
0481 edm::LogWarning("L1TCorrelatorLayer1Producer")
0482 << "Job running with multiple streams, but dump file will have only events on stream zero.";
0483 }
0484 }
0485 if (!patternWriterConfigs_.empty()) {
0486 if (id == 0) {
0487 for (const auto &pset : patternWriterConfigs_) {
0488 patternWriters_.emplace_back(std::make_unique<L1TCorrelatorLayer1PatternFileWriter>(pset, event_));
0489 }
0490 } else {
0491 edm::LogWarning("L1TCorrelatorLayer1Producer")
0492 << "Job running with multiple streams, but pattern files will be written only on stream zero.";
0493 }
0494 }
0495 }
0496
0497 void L1TCorrelatorLayer1Producer::endStream() {
0498 for (auto &writer : patternWriters_) {
0499 writer->flush();
0500 }
0501 }
0502
0503
0504 void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0505
0506 initEvent(iEvent);
0507
0508
0509 if (hasTracks_) {
0510 edm::Handle<l1t::PFTrackCollection> htracks;
0511 iEvent.getByToken(tkCands_, htracks);
0512 const auto &tracks = *htracks;
0513 for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) {
0514 const auto &tk = tracks[itk];
0515
0516 if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_)
0517 continue;
0518 if (tk.pt() > trkPt_) {
0519 addTrack(tk, l1t::PFTrackRef(htracks, itk));
0520 }
0521 }
0522 }
0523
0524
0525 edm::Handle<l1t::SAMuonCollection> muons;
0526 iEvent.getByToken(muCands_, muons);
0527 for (unsigned int i = 0, n = muons->size(); i < n; ++i) {
0528 const l1t::SAMuon &mu = (*muons)[i];
0529 if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_)
0530 continue;
0531 addMuon(mu, l1t::PFCandidate::MuonRef(muons, i));
0532 }
0533
0534
0535
0536 if (!emGCTRawCands_.isUninitialized()) {
0537 auto caloHandle = iEvent.getHandle(emGCTRawCands_);
0538 const auto &links = *caloHandle;
0539 for (unsigned int ic = 0; ic < links.size(); ++ic) {
0540 const auto &link = links[ic];
0541 for (unsigned int ie = 0; ie < link.size(); ++ie) {
0542 addGCTEmCaloRaw(link, ic, ie);
0543 }
0544 }
0545 }
0546
0547 if (!hadHGCalCands_.isUninitialized()) {
0548 auto caloHandle = iEvent.getHandle(hadHGCalCands_);
0549 if (caloHandle.isValid()) {
0550 const auto &calos = *caloHandle;
0551 for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
0552 const auto &calo = calos[ic];
0553 addHGCalHadCalo(calo, edm::Ptr<l1t::L1Candidate>(caloHandle, ic));
0554 }
0555 }
0556 }
0557
0558 if (!hadGCTRawCands_.isUninitialized()) {
0559 auto caloHandle = iEvent.getHandle(hadGCTRawCands_);
0560 const auto &links = *caloHandle;
0561 for (unsigned int ic = 0; ic < links.size(); ++ic) {
0562 const auto &link = links[ic];
0563 for (unsigned int ie = 0; ie < link.size(); ++ie) {
0564 addGCTHadCaloRaw(link, ic, ie);
0565 }
0566 }
0567 }
0568
0569 if (!hadGCTCands_.isUninitialized()) {
0570 auto caloHandle = iEvent.getHandle(hadGCTCands_);
0571 if (caloHandle.isValid()) {
0572 const auto &calos = *caloHandle;
0573 for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) {
0574 const auto &calo = calos[ic];
0575 addGCTHadCalo(calo, edm::Ptr<l1t::L1Candidate>(caloHandle, ic));
0576 }
0577 }
0578 }
0579
0580 regionizer_->run(event_.decoded, event_.pfinputs);
0581
0582
0583
0584 iEvent.put(fetchEmCalo(), "EmCalo");
0585 iEvent.put(fetchHadCalo(), "Calo");
0586 iEvent.put(fetchTracks(), "TK");
0587
0588 iEvent.put(fetchDecodedHadCalo(), "DecodedHadClusters");
0589 iEvent.put(fetchDecodedEmCalo(), "DecodedEmClusters");
0590 iEvent.put(fetchDecodedTracks(), "DecodedTK");
0591
0592
0593 std::vector<float> z0s;
0594 std::vector<std::pair<float, float>> ptsums;
0595 float z0 = 0;
0596 double ptsum = 0;
0597 l1t::VertexWord pvwd;
0598
0599 if (emuTkVtx_) {
0600 edm::Handle<std::vector<l1t::VertexWord>> vtxEmuHandle;
0601 iEvent.getByToken(tkVtxEmu_, vtxEmuHandle);
0602 for (const auto &vtx : *vtxEmuHandle) {
0603 ptsums.push_back(std::pair<float, float>(vtx.pt(), vtx.z0()));
0604 if (ptsum == 0 || vtx.pt() > ptsum) {
0605 ptsum = vtx.pt();
0606 pvwd = vtx;
0607 }
0608 }
0609 } else {
0610 edm::Handle<std::vector<l1t::Vertex>> vtxHandle;
0611 iEvent.getByToken(extTkVtx_, vtxHandle);
0612 for (const auto &vtx : *vtxHandle) {
0613 ptsums.push_back(std::pair<float, float>(vtx.pt(), vtx.z0()));
0614 if (ptsum == 0 || vtx.pt() > ptsum) {
0615 ptsum = vtx.pt();
0616 z0 = vtx.z0();
0617 }
0618 }
0619 pvwd = l1t::VertexWord(1, z0, 1, ptsum, 1, 1, 1);
0620 }
0621 l1ct::PVObjEmu hwpv;
0622 hwpv.hwZ0 = l1ct::Scales::makeZ0(pvwd.z0());
0623 event_.pvs.push_back(hwpv);
0624 event_.pvs_emu.push_back(pvwd.vertexWord());
0625
0626 if (nVtx_ > 1) {
0627 std::stable_sort(ptsums.begin(), ptsums.end(), [](const auto &a, const auto &b) { return a.first > b.first; });
0628 for (int i0 = 0; i0 < std::min(int(ptsums.size()), int(nVtx_)); i0++) {
0629 z0s.push_back(ptsums[i0].second);
0630 }
0631 for (unsigned int i = 1; i < z0s.size(); ++i) {
0632 l1ct::PVObjEmu hwpv;
0633 hwpv.hwZ0 = l1ct::Scales::makeZ0(z0s[i]);
0634 event_.pvs.push_back(hwpv);
0635 }
0636 }
0637
0638 #if 0
0639 iEvent.put(l1regions_.fetchTracks(0.0, true), "TKVtx");
0640 #endif
0641
0642
0643 event_.out.resize(event_.pfinputs.size());
0644 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0645 l1pfalgo_->run(event_.pfinputs[ir], event_.out[ir]);
0646 l1pfalgo_->mergeNeutrals(event_.out[ir]);
0647 l1tkegalgo_->run(event_.pfinputs[ir], event_.out[ir]);
0648 l1tkegalgo_->runIso(event_.pfinputs[ir], event_.pvs, event_.out[ir]);
0649 }
0650
0651
0652 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
0653 l1pualgo_->run(event_.pfinputs[ir], event_.pvs, event_.out[ir]);
0654
0655 }
0656
0657
0658
0659 std::vector<edm::Ref<BXVector<l1t::EGamma>>> egsta_refs;
0660 if (l1tkegalgo_->writeEgSta()) {
0661 putEgStaObjects(iEvent, "L1Eg");
0662 }
0663
0664
0665 for (auto &board : event_.board_out) {
0666 l1tkegsorter_->runPho(event_.pfinputs, event_.out, board.region_index, board.egphoton);
0667 l1tkegsorter_->runEle(event_.pfinputs, event_.out, board.region_index, board.egelectron);
0668 }
0669
0670
0671 iEvent.put(fetchPF(), "PF");
0672
0673
0674 putPuppi(iEvent);
0675
0676
0677 putEgObjects(iEvent, l1tkegalgo_->writeEgSta(), "L1TkEm", "L1TkEmPerBoard", "L1TkEle", "L1TkElePerBoard");
0678
0679
0680 for (int i = 0; i <= l1muType; ++i) {
0681 auto vecInputs = vecSecInput(InputType(i));
0682 auto tm = totAndMax(*vecInputs);
0683 addUInt(tm.first, std::string("totNSec") + inputTypeName[i], iEvent);
0684 addUInt(tm.second, std::string("maxNSec") + inputTypeName[i], iEvent);
0685 iEvent.put(std::move(vecInputs), std::string("vecNSec") + inputTypeName[i]);
0686 }
0687 for (int i = 0; i <= l1muType; ++i) {
0688 auto vecInputs = vecRegInput(InputType(i));
0689 auto tm = totAndMax(*vecInputs);
0690 addUInt(tm.first, std::string("totNReg") + inputTypeName[i], iEvent);
0691 addUInt(tm.second, std::string("maxNReg") + inputTypeName[i], iEvent);
0692 iEvent.put(std::move(vecInputs), std::string("vecNReg") + inputTypeName[i]);
0693 }
0694 for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) {
0695 auto vecPF = vecOutput(OutputType(i), false);
0696 auto tmPF = totAndMax(*vecPF);
0697 addUInt(tmPF.first, std::string("totNPF") + l1ct::OutputRegion::objTypeName[i], iEvent);
0698 addUInt(tmPF.second, std::string("maxNPF") + l1ct::OutputRegion::objTypeName[i], iEvent);
0699 iEvent.put(std::move(vecPF), std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]);
0700 auto vecPuppi = vecOutput(OutputType(i), true);
0701 auto tmPuppi = totAndMax(*vecPuppi);
0702 addUInt(tmPuppi.first, std::string("totNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent);
0703 addUInt(tmPuppi.second, std::string("maxNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent);
0704 iEvent.put(std::move(vecPuppi), std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]);
0705 }
0706
0707 if (fRegionDump_.is_open()) {
0708 event_.write(fRegionDump_);
0709 }
0710 for (auto &writer : patternWriters_) {
0711 writer->write(event_);
0712 }
0713
0714
0715 event_.clear();
0716 }
0717
0718 void L1TCorrelatorLayer1Producer::rawHgcalClusterEncode(ap_uint<256> &cwrd,
0719 const l1ct::DetectorSector<ap_uint<256>> &sec,
0720 const l1t::HGCalMulticluster &c) const {
0721 cwrd = 0;
0722
0723
0724 ap_ufixed<14, 12, AP_RND_CONV, AP_SAT> w_pt = c.pt();
0725
0726 ap_ufixed<14, 12, AP_RND_CONV, AP_SAT> w_empt = c.iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM);
0727
0728
0729
0730
0731 ap_uint<8> w_emfrac = std::min(round(c.eot() * 256), float(255.));
0732
0733
0734
0735 float em_frac_tot = c.hOverE() < 0 ? 0. : 1. / (c.hOverE() + 1.);
0736 ap_uint<8> w_emfrac_tot = std::min(round(em_frac_tot * 256), float(255.));
0737
0738
0739 static constexpr float ETAPHI_LSB = M_PI / 720;
0740 static constexpr float SIGMAZZ_LSB = 778.098 / (1 << 7);
0741 static constexpr float SIGMAPHIPHI_LSB = 0.12822 / (1 << 7);
0742 static constexpr float SIGMAETAETA_LSB = 0.148922 / (1 << 5);
0743
0744 ap_uint<10> w_eta = round(fabs(c.eta()) / ETAPHI_LSB);
0745 ap_int<9> w_phi = round(sec.region.localPhi(c.phi()) / ETAPHI_LSB);
0746
0747 ap_ufixed<12, 11, AP_RND_CONV, AP_SAT> w_meanz = fabs(c.zBarycenter()) - 320;
0748
0749 ap_uint<6> w_showerlength = c.showerLength();
0750 ap_uint<7> w_sigmazz = round(c.sigmaZZ() / SIGMAZZ_LSB);
0751 ap_uint<7> w_sigmaphiphi = round(c.sigmaPhiPhiTot() / SIGMAPHIPHI_LSB);
0752 ap_uint<6> w_coreshowerlength = c.coreShowerLength();
0753 ap_uint<5> w_sigmaetaeta = round(c.sigmaEtaEtaTot() / SIGMAETAETA_LSB);
0754
0755
0756 ap_uint<13> w_sigmarrtot = round(c.sigmaRRTot() * l1ct::Scales::SRRTOT_SCALE / l1ct::Scales::SRRTOT_LSB);
0757
0758
0759 cwrd(13, 0) = w_pt.range();
0760 cwrd(27, 14) = w_empt.range();
0761 cwrd(39, 32) = w_emfrac_tot;
0762 cwrd(47, 40) = w_emfrac;
0763
0764
0765 cwrd(64 + 9, 64 + 0) = w_eta;
0766 cwrd(64 + 18, 64 + 10) = w_phi;
0767 cwrd(64 + 30, 64 + 19) = w_meanz.range();
0768
0769 cwrd(128 + 18, 128 + 13) = w_showerlength;
0770 cwrd(128 + 38, 128 + 32) = w_sigmazz;
0771 cwrd(128 + 45, 128 + 39) = w_sigmaphiphi;
0772 cwrd(128 + 51, 128 + 46) = w_coreshowerlength;
0773 cwrd(128 + 56, 128 + 52) = w_sigmaetaeta;
0774
0775
0776
0777 cwrd(213, 201) = w_sigmarrtot;
0778 }
0779
0780 void L1TCorrelatorLayer1Producer::encodeAndAddHgcalCluster(ap_uint<256> &word,
0781 l1ct::DetectorSector<ap_uint<256>> &sec,
0782 const l1t::HGCalMulticluster &calo) const {
0783 rawHgcalClusterEncode(word, sec, calo);
0784 sec.obj.push_back(word);
0785 }
0786
0787 void L1TCorrelatorLayer1Producer::addEmPFCluster(const l1ct::EmCaloObjEmu &decCalo,
0788 const l1ct::PFRegionEmu ®ion,
0789 std::unique_ptr<l1t::PFClusterCollection> &pfClusters) const {
0790
0791 pfClusters->emplace_back(decCalo.floatPt(),
0792 region.floatGlbEta(decCalo.hwEta),
0793 region.floatGlbPhi(decCalo.hwPhi),
0794 decCalo.floatHoe(),
0795 true,
0796 decCalo.floatPtErr(),
0797 decCalo.intPt(),
0798 decCalo.intEta(),
0799 decCalo.intPhi());
0800
0801
0802 pfClusters->back().setHwQual(decCalo.hwEmID.to_int());
0803 pfClusters->back().setCaloDigi(decCalo);
0804 setRefs_(pfClusters->back(), decCalo);
0805 }
0806
0807 void L1TCorrelatorLayer1Producer::addDecodedEmCalo(l1ct::EmCaloObjEmu &decCalo,
0808 const edm::Ptr<l1t::L1Candidate> &caloPtr,
0809 l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec) {
0810 clusterRefMap_[caloPtr.get()] = caloPtr;
0811 decCalo.src = caloPtr.get();
0812 if (decCalo.hwPt > 0) {
0813
0814 const l1tp2::CaloCrystalCluster *crycl = dynamic_cast<const l1tp2::CaloCrystalCluster *>(decCalo.src);
0815 decCalo.hwShowerShape = l1ct::shower_shape_t(crycl->e2x5() / crycl->e5x5());
0816 decCalo.hwRelIso = l1ct::Scales::makeRelIso(crycl->isolation() / decCalo.hwPt.to_float());
0817 }
0818 sec.obj.push_back(decCalo);
0819 }
0820
0821 void L1TCorrelatorLayer1Producer::addHadPFCluster(const l1ct::HadCaloObjEmu &decCalo,
0822 const l1ct::PFRegionEmu ®ion,
0823 std::unique_ptr<l1t::PFClusterCollection> &pfClusters) const {
0824
0825 pfClusters->emplace_back(decCalo.floatPt(),
0826 region.floatGlbEta(decCalo.hwEta),
0827 region.floatGlbPhi(decCalo.hwPhi),
0828 decCalo.floatHoe(),
0829 decCalo.hwIsEM(),
0830 0.,
0831 decCalo.intPt(),
0832 decCalo.intEta(),
0833 decCalo.intPhi());
0834
0835
0836 pfClusters->back().setHwQual(decCalo.hwEmID.to_int());
0837 pfClusters->back().setCaloDigi(decCalo);
0838 setRefs_(pfClusters->back(), decCalo);
0839 }
0840
0841 void L1TCorrelatorLayer1Producer::addDecodedHadCalo(l1ct::HadCaloObjEmu &decCalo,
0842 const edm::Ptr<l1t::L1Candidate> &caloPtr,
0843 l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec) {
0844 clusterRefMap_[caloPtr.get()] = caloPtr;
0845 decCalo.src = caloPtr.get();
0846 sec.obj.push_back(decCalo);
0847 }
0848
0849 void L1TCorrelatorLayer1Producer::addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent) {
0850 iEvent.put(std::make_unique<unsigned>(value), iLabel);
0851 }
0852
0853 void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet &iConfig) {
0854
0855 unsigned int TF_phiSlices = 9;
0856 float TF_phiWidth = 2 * M_PI / TF_phiSlices;
0857 event_.decoded.track.clear();
0858 for (unsigned int ieta = 0, neta = 2; ieta < neta; ++ieta) {
0859 for (unsigned int iphi = 0; iphi < TF_phiSlices; ++iphi) {
0860 float phiCenter = reco::reducePhiRange(iphi * TF_phiWidth);
0861 event_.decoded.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth);
0862 event_.raw.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth);
0863 }
0864 }
0865
0866 event_.decoded.emcalo.clear();
0867 event_.decoded.hadcalo.clear();
0868 event_.raw.hgcalcluster.clear();
0869 event_.raw.gctEm.clear();
0870 event_.raw.gctHad.clear();
0871
0872 for (const edm::ParameterSet &preg : iConfig.getParameter<edm::VParameterSet>("caloSectors")) {
0873 std::vector<double> etaBoundaries = preg.getParameter<std::vector<double>>("etaBoundaries");
0874 if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end()))
0875 throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n");
0876 unsigned int phiSlices = preg.getParameter<uint32_t>("phiSlices");
0877 float phiWidth = 2 * M_PI / phiSlices;
0878 if (phiWidth > 2 * l1ct::Scales::maxAbsPhi())
0879 throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type");
0880 double phiZero = preg.getParameter<double>("phiZero");
0881 for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) {
0882 float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta];
0883 if (etaWidth > 2 * l1ct::Scales::maxAbsEta())
0884 throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type");
0885 for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) {
0886 float phiCenter = reco::reducePhiRange(iphi * phiWidth + phiZero);
0887 event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0888 event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0889 event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0890 event_.raw.gctEm.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0891 event_.raw.gctHad.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth);
0892 }
0893 }
0894 }
0895
0896 event_.decoded.muon.region = l1ct::PFRegionEmu(0., 0.);
0897 event_.raw.muon.region = l1ct::PFRegionEmu(0., 0.);
0898
0899 event_.pfinputs.clear();
0900 for (const edm::ParameterSet &preg : iConfig.getParameter<edm::VParameterSet>("regions")) {
0901 std::vector<double> etaBoundaries = preg.getParameter<std::vector<double>>("etaBoundaries");
0902 if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end()))
0903 throw cms::Exception("Configuration", "regions.etaBoundaries not sorted\n");
0904 unsigned int phiSlices = preg.getParameter<uint32_t>("phiSlices");
0905 float etaExtra = preg.getParameter<double>("etaExtra");
0906 float phiExtra = preg.getParameter<double>("phiExtra");
0907 float phiWidth = 2 * M_PI / phiSlices;
0908 for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) {
0909 for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) {
0910 float phiCenter = reco::reducePhiRange(iphi * phiWidth);
0911 event_.pfinputs.emplace_back(
0912 etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth, etaExtra, phiExtra);
0913 }
0914 }
0915 }
0916
0917 event_.board_out.clear();
0918 const edm::VParameterSet &board_params = iConfig.getParameter<edm::VParameterSet>("boards");
0919 event_.board_out.resize(board_params.size());
0920 for (unsigned int bidx = 0; bidx < board_params.size(); bidx++) {
0921 event_.board_out[bidx].region_index = board_params[bidx].getParameter<std::vector<unsigned int>>("regions");
0922 float etaBoard = 0.;
0923 float phiBoard = 0.;
0924 for (auto ridx : event_.board_out[bidx].region_index) {
0925 etaBoard += event_.pfinputs[ridx].region.floatEtaCenter();
0926 phiBoard += event_.pfinputs[ridx].region.floatPhiCenter();
0927 }
0928 event_.board_out[bidx].eta = etaBoard / event_.board_out[bidx].region_index.size();
0929 event_.board_out[bidx].phi = phiBoard / event_.board_out[bidx].region_index.size();
0930 }
0931 }
0932
0933 void L1TCorrelatorLayer1Producer::initEvent(const edm::Event &iEvent) {
0934 event_.clear();
0935 event_.run = iEvent.id().run();
0936 event_.lumi = iEvent.id().luminosityBlock();
0937 event_.event = iEvent.id().event();
0938 clusterRefMap_.clear();
0939 trackRefMap_.clear();
0940 muonRefMap_.clear();
0941 }
0942
0943 void L1TCorrelatorLayer1Producer::addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref) {
0944 auto &rawsectors = event_.raw.track;
0945 auto §ors = event_.decoded.track;
0946 assert(sectors.size() == 18 && rawsectors.size() == 18);
0947 int isec = t.track()->phiSector() + (t.eta() >= 0 ? 9 : 0);
0948 rawsectors[isec].obj.push_back(t.trackWord().getTrackWord());
0949 addDecodedTrack(sectors[isec], t);
0950 trackRefMap_[&t] = ref;
0951 }
0952 void L1TCorrelatorLayer1Producer::addMuon(const l1t::SAMuon &mu, l1t::PFCandidate::MuonRef ref) {
0953 event_.raw.muon.obj.emplace_back(mu.word());
0954 addDecodedMuon(event_.decoded.muon, mu);
0955 muonRefMap_[&mu] = ref;
0956 }
0957
0958 void L1TCorrelatorLayer1Producer::addGCTHadCalo(const l1t::PFCluster &calo, const edm::Ptr<l1t::L1Candidate> &caloPtr) {
0959 for (unsigned int isec = 0; isec < event_.decoded.hadcalo.size(); isec++) {
0960 auto &sec = event_.decoded.hadcalo[isec];
0961
0962 if (sec.region.contains(calo.eta(), calo.phi())) {
0963 l1ct::HadCaloObjEmu decCalo;
0964 getDecodedGCTPFCluster(decCalo, sec, calo);
0965 if (decCalo.floatPt() > hadPtCut_)
0966 addDecodedHadCalo(decCalo, caloPtr, sec);
0967 }
0968 }
0969 }
0970
0971 void L1TCorrelatorLayer1Producer::getDecodedGCTPFCluster(l1ct::HadCaloObjEmu &calo,
0972 l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec,
0973 const l1t::PFCluster &cluster) const {
0974 calo.clear();
0975 calo.hwPt = l1ct::Scales::makePtFromFloat(cluster.pt());
0976 calo.hwEta = l1ct::Scales::makeGlbEta(cluster.eta()) -
0977 sec.region.hwEtaCenter;
0978 calo.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(cluster.phi()));
0979 calo.hwEmPt = l1ct::Scales::makePtFromFloat(cluster.emEt());
0980 calo.hwEmID = cluster.hwEmID();
0981 calo.hwHoe = l1ct::Scales::makeHoe(cluster.hOverE());
0982 }
0983
0984 void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster &calo,
0985 const edm::Ptr<l1t::L1Candidate> &caloPtr) {
0986 for (unsigned int isec = 0; isec < event_.decoded.hadcalo.size(); isec++) {
0987 auto &sec = event_.decoded.hadcalo[isec];
0988
0989 if (sec.region.contains(calo.eta(), calo.phi())) {
0990 auto &sec_raw = event_.raw.hgcalcluster[isec];
0991
0992 ap_uint<256> cwrd = 0;
0993 encodeAndAddHgcalCluster(cwrd, sec_raw, calo);
0994
0995
0996 bool valid = true;
0997 l1ct::HadCaloObjEmu decCalo = hgcalInput_->decode(sec_raw.region, cwrd, valid);
0998 if (decCalo.floatPt() > hadPtCut_ && valid)
0999 addDecodedHadCalo(decCalo, caloPtr, sec);
1000 }
1001 }
1002 }
1003
1004 void L1TCorrelatorLayer1Producer::addGCTEmCaloRaw(const l1tp2::GCTEmDigiClusterLink &link,
1005 unsigned int linkidx,
1006 unsigned int entidx) {
1007
1008 auto caloIdx = calomapping[linkidx];
1009 if (caloIdx < event_.raw.gctEm.size()) {
1010 event_.raw.gctEm[caloIdx].obj.push_back(link[entidx].data());
1011 addDecodedGCTEmCalo(event_.decoded.emcalo[caloIdx], link[entidx]);
1012 }
1013 }
1014
1015 void L1TCorrelatorLayer1Producer::addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link,
1016 unsigned int linkidx,
1017 unsigned int entidx) {
1018
1019 auto caloIdx = calomapping[linkidx];
1020 if (caloIdx < event_.raw.gctHad.size()) {
1021 event_.raw.gctHad[caloIdx].obj.push_back(link[entidx].data());
1022 addDecodedGCTHadCalo(event_.decoded.hadcalo[caloIdx], link[entidx]);
1023 }
1024 }
1025
1026 void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector<l1ct::TkObjEmu> &sec, const l1t::PFTrack &t) {
1027 std::pair<l1ct::TkObjEmu, bool> tkAndSel;
1028 if (trackInput_) {
1029 tkAndSel = trackInput_->decodeTrack(t.trackWord().getTrackWord(), sec.region);
1030 } else {
1031 tkAndSel.first.hwPt = l1ct::Scales::makePtFromFloat(t.pt());
1032 tkAndSel.first.hwEta =
1033 l1ct::Scales::makeGlbEta(t.caloEta()) -
1034 sec.region.hwEtaCenter;
1035 tkAndSel.first.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(t.caloPhi()));
1036 tkAndSel.first.hwCharge = t.charge() > 0;
1037 tkAndSel.first.hwQuality = t.quality();
1038 tkAndSel.first.hwDEta = l1ct::Scales::makeEta(t.eta() - t.caloEta());
1039 tkAndSel.first.hwDPhi = l1ct::Scales::makePhi(std::abs(reco::deltaPhi(t.phi(), t.caloPhi())));
1040 tkAndSel.first.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z());
1041 tkAndSel.first.hwDxy = 0;
1042 tkAndSel.second = t.quality() > 0;
1043 }
1044
1045 tkAndSel.first.hwChi2 = round(t.chi2() * 10);
1046 tkAndSel.first.simPt = t.pt();
1047 tkAndSel.first.simCaloEta = t.caloEta();
1048 tkAndSel.first.simCaloPhi = t.caloPhi();
1049 tkAndSel.first.simVtxEta = t.eta();
1050 tkAndSel.first.simVtxPhi = t.phi();
1051 tkAndSel.first.simZ0 = t.vertex().Z();
1052 tkAndSel.first.simD0 = t.vertex().Rho();
1053 tkAndSel.first.src = &t;
1054
1055
1056
1057 if (!tkAndSel.second)
1058 tkAndSel.first.hwPt = 0;
1059 sec.obj.push_back(tkAndSel.first);
1060 }
1061
1062 void L1TCorrelatorLayer1Producer::addDecodedMuon(l1ct::DetectorSector<l1ct::MuObjEmu> &sec, const l1t::SAMuon &t) {
1063 l1ct::MuObjEmu mu;
1064 if (muonInput_) {
1065 mu = muonInput_->decode(t.word());
1066 } else {
1067 mu.hwPt = l1ct::Scales::makePtFromFloat(t.pt());
1068 mu.hwEta = l1ct::Scales::makeGlbEta(t.eta());
1069 mu.hwPhi = l1ct::Scales::makeGlbPhi(t.phi());
1070 mu.hwCharge = !t.hwCharge();
1071 mu.hwQuality = t.hwQual() / 2;
1072 mu.hwDEta = 0;
1073 mu.hwDPhi = 0;
1074 mu.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z());
1075 mu.hwDxy = 0;
1076 }
1077 mu.src = &t;
1078 sec.obj.push_back(mu);
1079 }
1080
1081 void L1TCorrelatorLayer1Producer::addDecodedGCTEmCalo(l1ct::DetectorSector<l1ct::EmCaloObjEmu> &sec,
1082 const l1tp2::GCTEmDigiCluster &digi) {
1083 l1ct::EmCaloObjEmu calo = gctEmInput_->decode(sec.region, digi.data());
1084
1085 auto caloPtr = edm::refToPtr(digi.clusterRef());
1086
1087 addDecodedEmCalo(calo, caloPtr, sec);
1088 }
1089
1090 void L1TCorrelatorLayer1Producer::addDecodedGCTHadCalo(l1ct::DetectorSector<l1ct::HadCaloObjEmu> &sec,
1091 const l1tp2::GCTHadDigiCluster &digi) {
1092 l1ct::HadCaloObjEmu calo = gctHadInput_->decode(sec.region, digi.data());
1093
1094 auto caloPtr = edm::refToPtr(digi.clusterRef());
1095
1096 addDecodedHadCalo(calo, caloPtr, sec);
1097 }
1098
1099 template <typename T>
1100 void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, const T &p) const {
1101 if (p.srcCluster) {
1102 auto match = clusterRefMap_.find(p.srcCluster);
1103 if (match == clusterRefMap_.end()) {
1104 throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt "
1105 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
1106 }
1107 pf.setCaloPtr(match->second);
1108 }
1109
1110 if (p.srcTrack) {
1111 auto match = trackRefMap_.find(p.srcTrack);
1112 if (match == trackRefMap_.end()) {
1113 throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.intId() << " pt "
1114 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
1115 }
1116 pf.setPFTrack(match->second);
1117 }
1118 if (p.srcMu) {
1119 auto match = muonRefMap_.find(p.srcMu);
1120 if (match == muonRefMap_.end()) {
1121 throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.intId() << " pt "
1122 << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi();
1123 }
1124 pf.setMuon(match->second);
1125 }
1126 }
1127
1128 template <>
1129 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::PFNeutralObjEmu>(const l1ct::PFNeutralObjEmu &key) const {
1130 return "Invalid pointer in Neutral PF candidate id " + std::to_string(key.intId()) + " pt " +
1131 std::to_string(key.floatPt()) + " eta " + std::to_string(key.floatEta()) + " phi " +
1132 std::to_string(key.floatPhi());
1133 }
1134
1135 template <>
1136 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::HadCaloObjEmu>(const l1ct::HadCaloObjEmu &key) const {
1137 return "Invalid pointer in hadcalo obj, pt " + std::to_string(key.floatPt()) + " eta " +
1138 std::to_string(key.floatEta()) + " phi " + std::to_string(key.floatPhi());
1139 }
1140
1141 template <>
1142 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::EmCaloObjEmu>(const l1ct::EmCaloObjEmu &key) const {
1143 return "Invalid pointer in emcalo obj, pt " + std::to_string(key.floatPt()) + " eta " +
1144 std::to_string(key.floatEta()) + " phi " + std::to_string(key.floatPhi());
1145 }
1146
1147 template <>
1148 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::TkObjEmu>(const l1ct::TkObjEmu &key) const {
1149 return "Invalid track pointer in track obj, pt " + std::to_string(key.floatPt()) + " eta " +
1150 std::to_string(key.floatEta()) + " phi " + std::to_string(key.floatPhi());
1151 }
1152
1153 template <>
1154 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::EGIsoObjEmu>(const l1ct::EGIsoObjEmu &key) const {
1155 return "Invalid cluster pointer in EGIso candidate, pt " + std::to_string(key.floatPt()) + " eta " +
1156 std::to_string(key.floatEta()) + " phi " + std::to_string(key.floatPhi());
1157 }
1158
1159 template <>
1160 std::string L1TCorrelatorLayer1Producer::refExcepMsg_<l1ct::EGIsoEleObjEmu>(const l1ct::EGIsoEleObjEmu &key) const {
1161 return "Invalid cluster pointer in EGEleIso candidate, pt " + std::to_string(key.floatPt()) + " eta " +
1162 std::to_string(key.floatEta()) + " phi " + std::to_string(key.floatPhi());
1163 }
1164
1165 template <>
1166 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::PFNeutralObjEmu>(l1t::PFCandidate &pf,
1167 const l1ct::PFNeutralObjEmu &p) const {
1168 if (p.srcCluster) {
1169 pf.setCaloPtr(findRef_(clusterRefMap_, p.srcCluster, p));
1170 }
1171 }
1172
1173 template <>
1174 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::HadCaloObjEmu>(l1t::PFCandidate &pf,
1175 const l1ct::HadCaloObjEmu &p) const {
1176 if (p.src) {
1177 pf.setCaloPtr(findRef_(clusterRefMap_, p.src, p));
1178 }
1179 }
1180
1181 template <>
1182 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::EmCaloObjEmu>(l1t::PFCandidate &pf,
1183 const l1ct::EmCaloObjEmu &p) const {
1184 if (p.src) {
1185 pf.setCaloPtr(findRef_(clusterRefMap_, p.src, p));
1186 }
1187 }
1188
1189 template <>
1190 void L1TCorrelatorLayer1Producer::setRefs_<l1ct::TkObjEmu>(l1t::PFCandidate &pf, const l1ct::TkObjEmu &p) const {
1191 if (p.src) {
1192 pf.setPFTrack(findRef_(trackRefMap_, p.src, p));
1193 }
1194 }
1195
1196 template <typename T>
1197 void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCluster &pf, const T &p) const {
1198 if (p.src) {
1199 pf.addConstituent(findRef_(clusterRefMap_, p.src, p));
1200 }
1201 }
1202
1203 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchHadCalo() const {
1204 auto ret = std::make_unique<l1t::PFCandidateCollection>();
1205 for (const auto &r : event_.pfinputs) {
1206 const auto ® = r.region;
1207 for (const auto &p : r.hadcalo) {
1208 if (p.hwPt == 0 || !reg.isFiducial(p))
1209 continue;
1210 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
1211 l1t::PFCandidate::ParticleType type = p.hwIsEM() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
1212 ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
1213 ret->back().setHwEmID(p.hwEmID);
1214 setRefs_(ret->back(), p);
1215 }
1216 }
1217 return ret;
1218 }
1219
1220 std::unique_ptr<l1t::PFClusterCollection> L1TCorrelatorLayer1Producer::fetchDecodedHadCalo() const {
1221 auto ret = std::make_unique<l1t::PFClusterCollection>();
1222 for (const auto &r : event_.pfinputs) {
1223 const auto ® = r.region;
1224 for (const auto &p : r.hadcalo) {
1225 if (p.hwPt == 0 || !reg.isFiducial(p))
1226 continue;
1227 addHadPFCluster(p, reg, ret);
1228 }
1229 }
1230 return ret;
1231 }
1232
1233 std::unique_ptr<l1t::PFClusterCollection> L1TCorrelatorLayer1Producer::fetchDecodedEmCalo() const {
1234 auto ret = std::make_unique<l1t::PFClusterCollection>();
1235 for (const auto &r : event_.pfinputs) {
1236 const auto ® = r.region;
1237 for (const auto &p : r.emcalo) {
1238 if (p.hwPt == 0 || !reg.isFiducial(p))
1239 continue;
1240 addEmPFCluster(p, reg, ret);
1241 }
1242 }
1243 return ret;
1244 }
1245
1246 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchEmCalo() const {
1247 auto ret = std::make_unique<l1t::PFCandidateCollection>();
1248 for (const auto &r : event_.pfinputs) {
1249 const auto ® = r.region;
1250 for (const auto &p : r.emcalo) {
1251 if (p.hwPt == 0 || !reg.isFiducial(p))
1252 continue;
1253 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
1254 ret->emplace_back(l1t::PFCandidate::Photon, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
1255 ret->back().setHwEmID(p.hwEmID);
1256 setRefs_(ret->back(), p);
1257 }
1258 }
1259 return ret;
1260 }
1261 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchTracks() const {
1262 auto ret = std::make_unique<l1t::PFCandidateCollection>();
1263 for (const auto &r : event_.pfinputs) {
1264 const auto ® = r.region;
1265 for (const auto &p : r.track) {
1266 if (p.hwPt == 0 || !reg.isFiducial(p))
1267 continue;
1268 reco::Particle::PolarLorentzVector p4(
1269 p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f);
1270 ret->emplace_back(l1t::PFCandidate::ChargedHadron, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi());
1271 setRefs_(ret->back(), p);
1272 }
1273 }
1274 return ret;
1275 }
1276
1277 std::unique_ptr<l1t::PFTrackCollection> L1TCorrelatorLayer1Producer::fetchDecodedTracks() const {
1278 auto ret = std::make_unique<l1t::PFTrackCollection>();
1279 for (const auto &r : event_.decoded.track) {
1280 const auto ® = r.region;
1281 for (const auto &p : r.obj) {
1282 if (p.hwPt == 0)
1283 continue;
1284 reco::Particle::PolarLorentzVector p4(
1285 p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0);
1286
1287 reco::Particle::Point vtx(0, 0, p.floatZ0());
1288
1289 ret->emplace_back(l1t::PFTrack(p.intCharge(),
1290 reco::Particle::LorentzVector(p4),
1291 vtx,
1292 p.src->track(),
1293 0,
1294 reg.floatGlbEta(p.hwEta),
1295 reg.floatGlbPhi(p.hwPhi),
1296 -1,
1297 -1,
1298 p.hwQuality.to_int(),
1299 false,
1300 p.intPt(),
1301 p.intEta(),
1302 p.intPhi()));
1303 }
1304 }
1305 return ret;
1306 }
1307
1308 std::unique_ptr<l1t::PFCandidateCollection> L1TCorrelatorLayer1Producer::fetchPF() const {
1309 auto ret = std::make_unique<l1t::PFCandidateCollection>();
1310 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
1311 const auto ® = event_.pfinputs[ir].region;
1312 for (const auto &p : event_.out[ir].pfcharged) {
1313 if (p.hwPt == 0 || !reg.isFiducial(p))
1314 continue;
1315 reco::Particle::PolarLorentzVector p4(
1316 p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f);
1317 l1t::PFCandidate::ParticleType type = l1t::PFCandidate::ChargedHadron;
1318 if (p.hwId.isMuon())
1319 type = l1t::PFCandidate::Muon;
1320 else if (p.hwId.isElectron())
1321 type = l1t::PFCandidate::Electron;
1322 ret->emplace_back(type, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi());
1323 ret->back().setZ0(p.floatZ0());
1324 ret->back().setDxy(p.floatDxy());
1325 ret->back().setHwZ0(p.hwZ0);
1326 ret->back().setHwDxy(p.hwDxy);
1327 ret->back().setHwTkQuality(p.hwTkQuality);
1328 ret->back().setCaloEta(reg.floatGlbEtaOf(p));
1329 ret->back().setCaloPhi(reg.floatGlbPhiOf(p));
1330
1331 setRefs_(ret->back(), p);
1332 }
1333 for (const auto &p : event_.out[ir].pfneutral) {
1334 if (p.hwPt == 0 || !reg.isFiducial(p))
1335 continue;
1336 reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f);
1337 l1t::PFCandidate::ParticleType type =
1338 p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
1339 ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi());
1340 ret->back().setHwEmID(p.hwEmID);
1341 ret->back().setCaloEta(reg.floatGlbEtaOf(p));
1342 ret->back().setCaloPhi(reg.floatGlbPhiOf(p));
1343 setRefs_(ret->back(), p);
1344 }
1345 }
1346 return ret;
1347 }
1348
1349 void L1TCorrelatorLayer1Producer::putPuppi(edm::Event &iEvent) const {
1350 auto refprod = iEvent.getRefBeforePut<l1t::PFCandidateCollection>("Puppi");
1351 auto coll = std::make_unique<l1t::PFCandidateCollection>();
1352 auto reg = std::make_unique<l1t::PFCandidateRegionalOutput>(refprod);
1353 std::vector<int> nobj;
1354 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
1355 nobj.clear();
1356 for (const auto &p : event_.out[ir].puppi) {
1357 if (p.hwPt == 0)
1358 continue;
1359
1360 l1t::PFCandidate::ParticleType type;
1361 float mass = 0.13f;
1362 if (p.hwId.charged()) {
1363 if (p.hwId.isMuon()) {
1364 type = l1t::PFCandidate::Muon;
1365 mass = 0.105;
1366 } else if (p.hwId.isElectron()) {
1367 type = l1t::PFCandidate::Electron;
1368 mass = 0.005;
1369 } else
1370 type = l1t::PFCandidate::ChargedHadron;
1371 } else {
1372 type = p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron;
1373 mass = p.hwId.isPhoton() ? 0.0 : 0.5;
1374 }
1375 reco::Particle::PolarLorentzVector p4(p.floatPt(), p.floatEta(), p.floatPhi(), mass);
1376 coll->emplace_back(type, p.intCharge(), p4, p.floatPuppiW(), p.intPt(), p.intEta(), p.intPhi());
1377 if (p.hwId.charged()) {
1378 coll->back().setZ0(p.floatZ0());
1379 coll->back().setDxy(p.floatDxy());
1380 coll->back().setHwZ0(p.hwZ0());
1381 coll->back().setHwDxy(p.hwDxy());
1382 coll->back().setHwTkQuality(p.hwTkQuality());
1383 } else {
1384 coll->back().setHwPuppiWeight(p.hwPuppiW());
1385 coll->back().setHwEmID(p.hwEmID());
1386 }
1387 coll->back().setEncodedPuppi64(p.pack().to_uint64());
1388 setRefs_(coll->back(), p);
1389 nobj.push_back(coll->size() - 1);
1390 }
1391 reg->addRegion(nobj, event_.pfinputs[ir].region.floatEtaCenter(), event_.pfinputs[ir].region.floatPhiCenter());
1392 }
1393 iEvent.put(std::move(coll), "Puppi");
1394 iEvent.put(std::move(reg), "PuppiRegional");
1395 }
1396
1397 void L1TCorrelatorLayer1Producer::putEgStaObjects(edm::Event &iEvent, const std::string &egLablel) const {
1398 auto egs = std::make_unique<BXVector<l1t::EGamma>>();
1399
1400
1401 for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) {
1402 const auto ® = event_.pfinputs[ir].region;
1403
1404
1405 for (unsigned int ieg = 0, neg = event_.out[ir].egsta.size(); ieg < neg; ++ieg) {
1406 const auto &p = event_.out[ir].egsta[ieg];
1407 if (p.hwPt == 0 || !reg.isFiducial(p))
1408 continue;
1409 l1t::EGamma eg(
1410 reco::Candidate::PolarLorentzVector(p.floatPt(), reg.floatGlbEta(p.hwEta), reg.floatGlbPhi(p.hwPhi), 0.));
1411 eg.setHwQual(p.hwQual);
1412 egs->push_back(0, eg);
1413 }
1414 }
1415
1416 iEvent.put(std::move(egs), egLablel);
1417 }
1418
1419 void L1TCorrelatorLayer1Producer::putEgObjects(edm::Event &iEvent,
1420 const bool writeEgSta,
1421 const std::string &tkEmLabel,
1422 const std::string &tkEmPerBoardLabel,
1423 const std::string &tkEleLabel,
1424 const std::string &tkElePerBoardLabel) const {
1425 auto tkems = std::make_unique<l1t::TkEmCollection>();
1426 auto tkemRefProd = iEvent.getRefBeforePut<l1t::TkEmCollection>(tkEmLabel);
1427 auto tkemPerBoard = std::make_unique<l1t::TkEmRegionalOutput>(tkemRefProd);
1428 auto tkeles = std::make_unique<l1t::TkElectronCollection>();
1429 auto tkeleRefProd = iEvent.getRefBeforePut<l1t::TkElectronCollection>(tkEleLabel);
1430 auto tkelePerBoard = std::make_unique<l1t::TkElectronRegionalOutput>(tkeleRefProd);
1431
1432
1433
1434 std::vector<int> nele_obj;
1435 std::vector<int> npho_obj;
1436
1437 for (const auto &board : event_.board_out) {
1438 npho_obj.clear();
1439 for (const auto &egiso : board.egphoton) {
1440 if (egiso.hwPt == 0)
1441 continue;
1442
1443 reco::Candidate::PolarLorentzVector mom(egiso.floatPt(), egiso.floatEta(), egiso.floatPhi(), 0.);
1444
1445 l1t::TkEm tkem(reco::Candidate::LorentzVector(mom),
1446 findRef_(clusterRefMap_, egiso.srcCluster, egiso),
1447 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIso),
1448 egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIsoPV));
1449 tkem.setHwQual(egiso.hwQual);
1450 tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso));
1451 tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV));
1452 tkem.setEgBinaryWord(egiso.pack(), l1t::TkEm::HWEncoding::CT);
1453 tkems->push_back(tkem);
1454 npho_obj.push_back(tkems->size() - 1);
1455 }
1456 tkemPerBoard->addRegion(npho_obj, board.eta, board.phi);
1457
1458 nele_obj.clear();
1459 for (const auto &egele : board.egelectron) {
1460 if (egele.hwPt == 0)
1461 continue;
1462
1463 reco::Candidate::PolarLorentzVector mom(egele.floatPt(), egele.floatVtxEta(), egele.floatVtxPhi(), 0.);
1464
1465 l1t::TkElectron tkele(reco::Candidate::LorentzVector(mom),
1466 findRef_(clusterRefMap_, egele.srcCluster, egele),
1467 edm::refToPtr(egele.srcTrack->track()),
1468 egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso));
1469 tkele.setHwQual(egele.hwQual);
1470 tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso));
1471 tkele.setEgBinaryWord(egele.pack(), l1t::TkElectron::HWEncoding::CT);
1472 tkele.setIdScore(egele.floatIDScore());
1473 tkele.setCharge(egele.intCharge());
1474 tkele.setTrkzVtx(egele.floatZ0());
1475 tkeles->push_back(tkele);
1476 nele_obj.push_back(tkeles->size() - 1);
1477 }
1478 tkelePerBoard->addRegion(nele_obj, board.eta, board.phi);
1479 }
1480
1481 iEvent.put(std::move(tkems), tkEmLabel);
1482 iEvent.put(std::move(tkemPerBoard), tkEmPerBoardLabel);
1483 iEvent.put(std::move(tkeles), tkEleLabel);
1484 iEvent.put(std::move(tkelePerBoard), tkElePerBoardLabel);
1485 }
1486
1487 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecSecInput(InputType t) const {
1488 auto v = std::make_unique<std::vector<unsigned>>();
1489 {
1490 switch (t) {
1491 case caloType:
1492 for (const auto &s : event_.decoded.hadcalo)
1493 v->push_back(s.size());
1494 break;
1495 case emcaloType:
1496 for (const auto &s : event_.decoded.emcalo)
1497 v->push_back(s.size());
1498 break;
1499 case trackType:
1500 for (const auto &s : event_.decoded.track)
1501 v->push_back(s.size());
1502 break;
1503 case l1muType:
1504 v->push_back(event_.decoded.muon.size());
1505 break;
1506 }
1507 }
1508 return v;
1509 }
1510
1511 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecRegInput(InputType t) const {
1512 auto v = std::make_unique<std::vector<unsigned>>();
1513 for (const auto ® : event_.pfinputs) {
1514 switch (t) {
1515 case caloType:
1516 v->push_back(reg.hadcalo.size());
1517 break;
1518 case emcaloType:
1519 v->push_back(reg.emcalo.size());
1520 break;
1521 case trackType:
1522 v->push_back(reg.track.size());
1523 break;
1524 case l1muType:
1525 v->push_back(reg.muon.size());
1526 break;
1527 }
1528 }
1529 return v;
1530 }
1531
1532 std::unique_ptr<std::vector<unsigned>> L1TCorrelatorLayer1Producer::vecOutput(OutputType i, bool usePuppi) const {
1533 auto v = std::make_unique<std::vector<unsigned>>();
1534 for (const auto ® : event_.out) {
1535 v->push_back(reg.nObj(i, usePuppi));
1536 }
1537 return v;
1538 }
1539 std::pair<unsigned int, unsigned int> L1TCorrelatorLayer1Producer::totAndMax(
1540 const std::vector<unsigned> &perRegion) const {
1541 unsigned int ntot = 0, nmax = 0;
1542 for (unsigned ni : perRegion) {
1543 ntot += ni;
1544 nmax = std::max(nmax, ni);
1545 }
1546 return std::make_pair(ntot, nmax);
1547 }
1548
1549 #include "FWCore/Framework/interface/MakerMacros.h"
1550 DEFINE_FWK_MODULE(L1TCorrelatorLayer1Producer);