diff --git a/DPGAnalysis/Phase2L1TNanoAOD/python/l1tPh2Nanotables_cff.py b/DPGAnalysis/Phase2L1TNanoAOD/python/l1tPh2Nanotables_cff.py index 871445f2d0281..d3de5f2389dd8 100644 --- a/DPGAnalysis/Phase2L1TNanoAOD/python/l1tPh2Nanotables_cff.py +++ b/DPGAnalysis/Phase2L1TNanoAOD/python/l1tPh2Nanotables_cff.py @@ -394,12 +394,13 @@ ) sc8JetTable = pfJetTable.clone( - src = 'l1tSC8PFL1PuppiCorrectedEmulator', + src = cms.InputTag('l1tSC82ProngJetProducer', 'l1tSC82ProngJets'), name = "L1puppiJetSC8", doc = "SeededCone 0.8 Puppi jet, origin: Correlator", variables = cms.PSet( pfJetTable.variables.clone(), - mass = Var("mass", float) + mass = Var("mass", float), + nprongTagScore = Var('getTagScore("nprong")', float) ) ) @@ -580,7 +581,7 @@ # ## jets sc4JetTable, sc8JetTable, - sc4ExtJetTable, + sc4ExtJetTable, sc4NGJetTable, histoJetTable, caloJetTable, diff --git a/DataFormats/L1TParticleFlow/interface/jets.h b/DataFormats/L1TParticleFlow/interface/jets.h index 9a49248309765..aa41a0ef86aef 100644 --- a/DataFormats/L1TParticleFlow/interface/jets.h +++ b/DataFormats/L1TParticleFlow/interface/jets.h @@ -15,7 +15,7 @@ namespace l1ct { // all possible tag categories (can be extended for new / separate taggers) class JetTagClass { public: - enum JetTagClassValue : uint8_t { b, c, uds, g, tau_p, tau_n, mu, e }; + enum JetTagClassValue : uint8_t { b, c, uds, g, tau_p, tau_n, mu, e, nprong }; JetTagClass() = default; JetTagClass(JetTagClassValue aJetTagClassValue) : value_(aJetTagClassValue) {} JetTagClass(std::string aJetTagClassValueString) { @@ -47,7 +47,7 @@ namespace l1ct { // Define a separate class/struct for jet tag handling struct JetTagClassHandler { - static const unsigned NTagFields = 8; + static const unsigned NTagFields = 9; static const JetTagClass tagClassesDefault_[NTagFields]; JetTagClass tagClassesArray[NTagFields]; @@ -197,7 +197,7 @@ namespace l1ct { j.v3.phi = CTtoGT_phi(hwPhi); j.v3.eta = CTtoGT_eta(hwEta); j.z0(l1ct::z0_t::width - 1, 0) = hwZ0(l1ct::z0_t::width - 1, 0); - j.hwNProngScore = 0; + j.hwNProngScore = hwTagScores[0]; // currently only one WideJet tagger j.hwMassSq = CTtoGT_massSq(hwMassSq); return j; diff --git a/DataFormats/L1TParticleFlow/src/jets.cpp b/DataFormats/L1TParticleFlow/src/jets.cpp index 3c585c70fe987..f147c94d2c68f 100644 --- a/DataFormats/L1TParticleFlow/src/jets.cpp +++ b/DataFormats/L1TParticleFlow/src/jets.cpp @@ -8,7 +8,8 @@ const std::unordered_map l1ct: {"tau_p", l1ct::JetTagClass::JetTagClassValue::tau_p}, {"tau_n", l1ct::JetTagClass::JetTagClassValue::tau_n}, {"mu", l1ct::JetTagClass::JetTagClassValue::mu}, - {"e", l1ct::JetTagClass::JetTagClassValue::e}}; + {"e", l1ct::JetTagClass::JetTagClassValue::e}, + {"nprong", l1ct::JetTagClass::JetTagClassValue::nprong}}; const l1ct::JetTagClass l1ct::JetTagClassHandler::tagClassesDefault_[NTagFields] = {l1ct::JetTagClass("b"), l1ct::JetTagClass("c"), @@ -17,4 +18,5 @@ const l1ct::JetTagClass l1ct::JetTagClassHandler::tagClassesDefault_[NTagFields] l1ct::JetTagClass("tau_p"), l1ct::JetTagClass("tau_n"), l1ct::JetTagClass("mu"), - l1ct::JetTagClass("e")}; + l1ct::JetTagClass("e"), + l1ct::JetTagClass("nprong")}; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h new file mode 100644 index 0000000000000..a1f5c9e1e117b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h @@ -0,0 +1,45 @@ +#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOWS_L1TSC82ProngJetID_H +#define L1TRIGGER_PHASE2L1PARTICLEFLOWS_L1TSC82ProngJetID_H + +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include +#include + +//HLS4ML compiled emulator modeling +#include "ap_fixed.h" +#include "hls4ml/emulator.h" + +class L1TSC82ProngJetID { +public: + L1TSC82ProngJetID(const std::shared_ptr model, int iNParticles); + + typedef ap_fixed<24, 12, AP_RND, AP_SAT, 0> inputtype; + typedef ap_ufixed<20, 10, AP_RND, AP_SAT, 0> prong_score; + + void setNNVectorVar(); + std::vector EvaluateNNFixed(); + std::vector computeFixed(const l1t::PFJet &iJet); + +private: + std::vector NNvectorVar_; + int fNParticles_; + std::unique_ptr fPt_; + std::unique_ptr fPt_rel_; + std::unique_ptr fDEta_; + std::unique_ptr fDPhi_; + std::unique_ptr fPt_log_; + std::unique_ptr fMass_; + std::unique_ptr fZ0_; + std::unique_ptr fDxy_; + std::unique_ptr fIs_filled_; + std::unique_ptr fPuppi_weight_; + std::unique_ptr fEmID_; + std::unique_ptr fQuality_; + + std::unique_ptr fCharge_; + std::unique_ptr fId_; + std::shared_ptr modelRef_; + + //bool isDebugEnabled_; +}; +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TSC82ProngJetModelProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TSC82ProngJetModelProducer.cc new file mode 100644 index 0000000000000..a8bb606acb5d7 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TSC82ProngJetModelProducer.cc @@ -0,0 +1,108 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" + +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "DataFormats/JetReco/interface/Jet.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h" +#include "DataFormats/Common/interface/ValueMap.h" + +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +#include +#include + +#include +#include "ap_fixed.h" +#include "hls4ml/emulator.h" + +using namespace l1t; + +class L1TSC82ProngJetProducer : public edm::stream::EDProducer<> { +public: + explicit L1TSC82ProngJetProducer(const edm::ParameterSet&); + ~L1TSC82ProngJetProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + std::unique_ptr fJetId_; + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; + + edm::EDGetTokenT> const jets_; + double const fMinPt_; + double const fMaxEta_; + unsigned int const fMaxJets_; + int const fNParticles_; + + hls4mlEmulator::ModelLoader loader; + std::shared_ptr model; +}; + +L1TSC82ProngJetProducer::L1TSC82ProngJetProducer(const edm::ParameterSet& cfg) + : jets_(consumes>(cfg.getParameter("jets"))), + fMinPt_(cfg.getParameter("minPt")), + fMaxEta_(cfg.getParameter("maxEta")), + fMaxJets_(cfg.getParameter("maxJets")), + fNParticles_(cfg.getParameter("nParticles")), + loader(hls4mlEmulator::ModelLoader(cfg.getParameter("l1tSC82ProngJetModelPath"))) { + model = loader.load_model(); + fJetId_ = std::make_unique(model, fNParticles_); + produces("l1tSC82ProngJets"); +} + +void L1TSC82ProngJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + edm::Handle> jets; + iEvent.getByToken(jets_, jets); + std::vector taggedJets; + + for (const auto& srcjet : *jets) { + l1ct::Jet ctHWJet = l1ct::Jet::unpack(srcjet.encodedJet(l1t::PFJet::HWEncoding::CT)); + + if (srcjet.pt() < fMinPt_ || std::abs(srcjet.eta()) > fMaxEta_ || taggedJets.size() >= fMaxJets_) { + ctHWJet.clear(); + continue; + } + std::vector JetProngScore_float = fJetId_->computeFixed(srcjet); + l1gt::WideJet gtwHWJet = l1gt::WideJet::unpack(srcjet.getHWJetGTWide()); + + l1t::PFJet edmJet( + srcjet.pt(), srcjet.eta(), srcjet.phi(), srcjet.mass(), gtwHWJet.v3.pt.V, gtwHWJet.v3.eta.V, gtwHWJet.v3.phi.V); + + std::vector classes{l1ct::JetTagClass(l1ct::JetTagClass::JetTagClassValue::nprong)}; + + edmJet.addTagScores(JetProngScore_float, classes, 1.); + edmJet.setEncodedJet(l1t::PFJet::HWEncoding::CT, ctHWJet.pack()); + edmJet.setEncodedJet(l1t::PFJet::HWEncoding::GTWide, gtwHWJet.pack()); + + std::vector> constituents; + std::for_each(srcjet.constituents().begin(), srcjet.constituents().end(), [&](auto constituent) { + edmJet.addConstituent(constituent); + }); + + taggedJets.push_back(edmJet); + } + std::sort(taggedJets.begin(), taggedJets.end(), [](l1t::PFJet a, l1t::PFJet b) { return (a.pt() > b.pt()); }); + + std::unique_ptr taggedJetsCollection(new l1t::PFJetCollection); + taggedJetsCollection->swap(taggedJets); + iEvent.put(std::move(taggedJetsCollection), "l1tSC82ProngJets"); +} + +void L1TSC82ProngJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("jets", edm::InputTag("l1tSC8PFL1PuppiEmulator")); + desc.add("l1tSC82ProngJetModelPath", std::string("L1TSC82ProngJetModel_v0")); + desc.add("minPt", 0.); + desc.add("maxEta", 5.); + desc.add("maxJets", 16); + desc.add("nParticles", 8); + descriptions.add("l1tSC82ProngJetProducer", desc); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TSC82ProngJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 508810eddf4b9..5c3a8e3543f37 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -213,13 +213,10 @@ emulateCorrections = cms.bool(False), # NOTE: should switch this on for FW bit-wise agreement! emInterpScenario = cms.string("allKeepHad"), # for all clusters, use EM intepretation to redefine the EM part of the energy ), - regionizerAlgo = cms.string("Multififo"), + regionizerAlgo = cms.string("BufferedFoldedMultififo"), regionizerAlgoParameters = cms.PSet( useAlsoVtxCoords = cms.bool(True), - nEndcaps = cms.uint32(2), - nClocks = cms.uint32(54), - nTkLinks = cms.uint32(2), - nCaloLinks = cms.uint32(3), + nClocks = cms.uint32(162), nTrack = cms.uint32(30), nCalo = cms.uint32(20), nEmCalo = cms.uint32(10), @@ -365,13 +362,10 @@ emulateCorrections = cms.bool(False), # NOTE: should switch this on for FW bit-wise agreement! emInterpScenario = cms.string("allKeepHad"), # for all clusters, use EM intepretation to redefine the EM part of the energy ), - regionizerAlgo = cms.string("Multififo"), + regionizerAlgo = cms.string("BufferedFoldedMultififo"), regionizerAlgoParameters = cms.PSet( useAlsoVtxCoords = cms.bool(True), - nEndcaps = cms.uint32(2), - nClocks = cms.uint32(54), - nTkLinks = cms.uint32(0), - nCaloLinks = cms.uint32(3), + nClocks = cms.uint32(162), nTrack = cms.uint32(0), nCalo = cms.uint32(12), nEmCalo = cms.uint32(12), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index 11a874344a1ee..f8ac89ffa96ed 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -73,54 +73,32 @@ inPatternFile=cms.PSet( nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link format=cms.string("EMPv2"), - outputFilename=cms.string("L1TCTL2EG_InPattern"), + outputFilename=cms.string("L1TCTL2EG_TMUX18_InPattern"), outputFileExtension=cms.string("txt.gz"), TMUX=cms.uint32(6), maxLinesPerFile=cms.uint32(1024), eventsPerFile=cms.uint32(12), channels=cms.VPSet( cms.PSet( - TMUX=cms.uint32(6), - nWords=cms.uint32(48), # = 16*2words ele + 16words photons + TMUX=cms.uint32(18), + nWords=cms.uint32(156), # = (16*2words ele + 16words photons) * 3 (regions) every 6 BX (54 words) = 48+6(empty)+48+6(empty)+48 = 156 interface=cms.string("eglayer1Barrel"), id=cms.uint32(0), - channels=cms.vuint32(0) - ), - cms.PSet( - TMUX=cms.uint32(6), - nWords=cms.uint32(48), - interface=cms.string("eglayer1Barrel"), - id=cms.uint32(1), - channels=cms.vuint32(1) + channels=cms.vuint32(0,2,4) ), cms.PSet( - TMUX=cms.uint32(6), - nWords=cms.uint32(48), - interface=cms.string("eglayer1Barrel"), - id=cms.uint32(2), - channels=cms.vuint32(2) - ), - cms.PSet( - TMUX=cms.uint32(6), - nWords=cms.uint32(48), + TMUX=cms.uint32(18), + nWords=cms.uint32(129), # (16*2words ele + 16words photons) * 2 (regions) every 9 BX (81 words) = 48+33(empty)+48 interface=cms.string("eglayer1Endcap"), - id=cms.uint32(3), - channels=cms.vuint32(3) - ), - cms.PSet( - TMUX=cms.uint32(6), - nWords=cms.uint32(48), - interface=cms.string("eglayer1Endcap"), - id=cms.uint32(4), - channels=cms.vuint32(4) + id=cms.uint32(1), + channels=cms.vuint32(1,3,5) ), - ) ), outPatternFile=cms.PSet( nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link format=cms.string("EMPv2"), - outputFilename=cms.string("L1TCTL2EG_OutPattern"), + outputFilename=cms.string("L1TCTL2EG_TMUX18_OutPattern"), outputFileExtension=cms.string("txt.gz"), TMUX=cms.uint32(6), maxLinesPerFile=cms.uint32(1024), @@ -162,7 +140,7 @@ regions=cms.vint32(3, 4) ), cms.PSet( - pfProducer=cms.InputTag("l1tLayer1Barrel", 'L1TkElePerBoard'), + pfProducer=cms.InputTag("l1tLayer1BarrelElliptic", 'L1TkElePerBoard'), regions=cms.vint32(0, 1, 2) ), ), @@ -176,7 +154,7 @@ regions=cms.vint32(-1) ), cms.PSet( - pfProducer=cms.InputTag("l1tLayer1Barrel", 'L1TkEmPerBoard'), + pfProducer=cms.InputTag("l1tLayer1BarrelElliptic", 'L1TkEmPerBoard'), regions=cms.vint32(0, 1, 2) ), ), @@ -192,66 +170,6 @@ ), ) -# EG Layer2 with Layer1 @ TMUX18 -l1tLayer2EGTM18 = l1tLayer2EG.clone( - tkElectrons=cms.VPSet( - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1HGCalTM18", 'L1TkElePerBoard'), - regions=cms.vint32(3, 4) - ), - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1BarrelSerenityTM18", 'L1TkElePerBoard'), - regions=cms.vint32(0, 1, 2) - ), - ), - tkEms=cms.VPSet( - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1HGCalTM18", 'L1TkEmPerBoard'), - regions=cms.vint32(3, 4) - ), - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1HGCalNoTKTM18", 'L1TkEmPerBoard'), - regions=cms.vint32(-1) - ), - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1BarrelSerenityTM18", 'L1TkEmPerBoard'), - regions=cms.vint32(0, 1, 2) - ), - ), - tkEgs=cms.VPSet( - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1HGCalTM18", 'L1Eg'), - regions=cms.vint32(-1) - ), - cms.PSet( - pfProducer=cms.InputTag("l1tLayer1HGCalNoTKTM18", 'L1Eg'), - regions=cms.vint32(-1) - ), - ), -) - -l1tLayer2EGTM18.inPatternFile.outputFilename = "L1TCTL2EG_TMUX18_InPattern" -l1tLayer2EGTM18.inPatternFile.channels = cms.VPSet( - cms.PSet( - TMUX=cms.uint32(18), - nWords=cms.uint32(156), # = (16*2words ele + 16words photons) * 3 (regions) every 6 BX (54 words) = 48+6(empty)+48+6(empty)+48 = 156 - interface=cms.string("eglayer1Barrel"), - id=cms.uint32(0), - channels=cms.vuint32(0,2,4) - ), - cms.PSet( - TMUX=cms.uint32(18), - nWords=cms.uint32(129), # (16*2words ele + 16words photons) * 2 (regions) every 9 BX (81 words) = 48+33(empty)+48 - interface=cms.string("eglayer1Endcap"), - id=cms.uint32(1), - channels=cms.vuint32(1,3,5) - ), -) -l1tLayer2EGTM18.outPatternFile.outputFilename = 'L1TCTL2EG_TMUX18_OutPattern' -# FIXME: we need to schedule a new deregionizer for TM18 -# l1tLayer2EGTM18.l1PFObjects = cms.InputTag("l1tLayer2Deregionizer", "Puppi"), - - L1TLayer2EGTask = cms.Task( l1tLayer2Deregionizer, l1tLayer2EG, diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py index c3fb6c41d509a..4f19902b7c3dd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py @@ -60,9 +60,12 @@ correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root"), correctorDir = cms.string('L1PuppiSC4EmuJets')) + +l1tSC82ProngJetProducer = l1tSC4NGJetProducer.clone() + L1TPFJetsTask = cms.Task( l1tLayer2Deregionizer, l1tSC4PFL1PF, l1tSC4PFL1Puppi, l1tSC4PFL1PuppiCorrected, l1tSC8PFL1Puppi, l1tSC8PFL1PuppiCorrected, l1tSC4PFL1PuppiEmulator, l1tSC4PFL1PuppiCorrectedEmulator, l1tSC4PFL1PuppiCorrectedEmulatorMHT, - l1tSC8PFL1PuppiEmulator, l1tSC8PFL1PuppiCorrectedEmulator + l1tSC8PFL1PuppiEmulator, l1tSC8PFL1PuppiCorrectedEmulator, l1tSC82ProngJetProducer ) L1TPFJetsExtendedTask = cms.Task( @@ -71,5 +74,5 @@ L1TPFJetsEmulationTask = cms.Task( l1tLayer2Deregionizer, l1tSC4PFL1PuppiEmulator, l1tSC4PFL1PuppiCorrectedEmulator, l1tSC4PFL1PuppiCorrectedEmulatorMHT, - l1tSC8PFL1PuppiEmulator, l1tSC8PFL1PuppiCorrectedEmulator + l1tSC8PFL1PuppiEmulator, l1tSC8PFL1PuppiCorrectedEmulator, l1tSC82ProngJetProducer ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TSC82ProngJetID.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TSC82ProngJetID.cc new file mode 100644 index 0000000000000..20e8a97f25040 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TSC82ProngJetID.cc @@ -0,0 +1,154 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include +#include + +L1TSC82ProngJetID::L1TSC82ProngJetID(const std::shared_ptr model, int iNParticles) + : modelRef_(model) { + NNvectorVar_.clear(); + fNParticles_ = iNParticles; + + fPt_ = std::make_unique(fNParticles_); + fPt_rel_ = std::make_unique(fNParticles_); + fDEta_ = std::make_unique(fNParticles_); + fDPhi_ = std::make_unique(fNParticles_); + fPt_log_ = std::make_unique(fNParticles_); + fMass_ = std::make_unique(fNParticles_); + fZ0_ = std::make_unique(fNParticles_); + fDxy_ = std::make_unique(fNParticles_); + fIs_filled_ = std::make_unique(fNParticles_); + fPuppi_weight_ = std::make_unique(fNParticles_); + fEmID_ = std::make_unique(fNParticles_); + fQuality_ = std::make_unique(fNParticles_); + + fId_ = std::make_unique(fNParticles_); + fCharge_ = std::make_unique(fNParticles_); +} + +void L1TSC82ProngJetID::setNNVectorVar() { + NNvectorVar_.clear(); + for (int i0 = 0; i0 < fNParticles_; i0++) { + NNvectorVar_.push_back(fPt_.get()[i0]); // pt + NNvectorVar_.push_back(fPt_rel_.get()[i0]); //pT as a fraction of jet pT + NNvectorVar_.push_back(fPt_log_.get()[i0]); // pt log + NNvectorVar_.push_back(fDEta_.get()[i0]); //dEta from jet axis + NNvectorVar_.push_back(fDPhi_.get()[i0]); //dPhi from jet axis + NNvectorVar_.push_back(fMass_.get()[i0]); // Mass + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Photon); // Photon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron && fCharge_.get()[i0] > 0); // Positron + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron && fCharge_.get()[i0] < 0); // Electron + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon && fCharge_.get()[i0] > 0); // Anti-muon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon && fCharge_.get()[i0] < 0); // Muon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::NeutralHadron); // Neutral Had + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron && fCharge_.get()[i0] > 0); // Anti-Pion + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron && fCharge_.get()[i0] < 0); // Pion + NNvectorVar_.push_back(fZ0_.get()[i0]); // z0 + NNvectorVar_.push_back(fDxy_.get()[i0]); // dxy + NNvectorVar_.push_back(fIs_filled_.get()[i0]); // isfilled + NNvectorVar_.push_back(fPuppi_weight_.get()[i0]); // puppi weight + NNvectorVar_.push_back(fEmID_.get()[i0]); // emID + NNvectorVar_.push_back(fQuality_.get()[i0]); // quality + } +} + +std::vector L1TSC82ProngJetID::EvaluateNNFixed() { + const unsigned int NInputs = 160; + const unsigned int FeaturesPerParticle = 20; + + if (fNParticles_ * FeaturesPerParticle != NInputs) { + throw std::runtime_error( + "L1TSC82ProngJetID::EvaluateNNFixed: " + "Model expects exactly 8 particles (160 inputs), but fNParticles_ = " + + std::to_string(fNParticles_)); + } + + prong_score prong_scores; + inputtype fillzero = 0.0; + + inputtype modelInput[NInputs]; + std::fill(std::begin(modelInput), std::end(modelInput), fillzero); + + for (unsigned int i = 0; i < NInputs; i++) { + modelInput[i] = NNvectorVar_[i]; + } + + modelRef_->prepare_input(modelInput); + modelRef_->predict(); + modelRef_->read_result(&prong_scores); + + std::vector prong_score_; + prong_score_.push_back(prong_scores.to_float()); + + return prong_score_; +} //end EvaluateNNFixed + +std::vector L1TSC82ProngJetID::computeFixed(const l1t::PFJet &iJet) { + for (int i0 = 0; i0 < fNParticles_; i0++) { + fPt_rel_.get()[i0] = 0; + fPt_.get()[i0] = 0; + fDEta_.get()[i0] = 0; + fDPhi_.get()[i0] = 0; + fPt_log_.get()[i0] = 0; + fMass_.get()[i0] = 0; + fZ0_.get()[i0] = 0; + fDxy_.get()[i0] = 0; + fIs_filled_.get()[i0] = 0; + fPuppi_weight_.get()[i0] = 0; + fEmID_.get()[i0] = 0; + fQuality_.get()[i0] = 0; + + fId_.get()[i0] = 0; + fCharge_.get()[i0] = 0; + } + auto iParts = iJet.constituents(); + std::sort(iParts.begin(), iParts.end(), [](edm::Ptr i, edm::Ptr j) { + return (i->pt() > j->pt()); + }); + + l1ct::Jet ctJet = l1ct::Jet::unpack(iJet.getHWJetCT()); + float jet_pt_ = ctJet.floatPt(); + float jet_eta_ = ctJet.floatEta(); + float jet_phi_ = ctJet.floatPhi(); + + for (unsigned int i0 = 0; i0 < iParts.size(); i0++) { + if (i0 >= (unsigned int)fNParticles_) + break; + fPt_.get()[i0] = iParts[i0]->pt(); + fZ0_.get()[i0] = iParts[i0]->z0(); + fPt_rel_.get()[i0] = iParts[i0]->pt() / jet_pt_; + fPt_log_.get()[i0] = std::log(iParts[i0]->pt()); + fDEta_.get()[i0] = jet_eta_ - float(iParts[i0]->eta()); + + if (1 < iParts[i0]->phi() - jet_phi_) { + fDPhi_.get()[i0] = 1; + } else if (-1 > iParts[i0]->phi() - jet_phi_) { + fDPhi_.get()[i0] = -1; + } else { + fDPhi_.get()[i0] = iParts[i0]->phi() - jet_phi_; + } + + fIs_filled_.get()[i0] = 1; + + float massCand = 0.13f; + if (abs(iParts[i0]->charge())) { + if ((iParts[i0]->id() == l1t::PFCandidate::Muon)) { + massCand = 0.105; + } else if ((iParts[i0]->id() == l1t::PFCandidate::Electron)) { + massCand = 0.005; + } + } else { + massCand = iParts[i0]->id() == l1t::PFCandidate::Photon ? 0.0 : 0.5; + } + + fMass_.get()[i0] = massCand; + fPuppi_weight_.get()[i0] = iParts[i0]->puppiWeight(); + fId_.get()[i0] = iParts[i0]->id(); + fCharge_.get()[i0] = iParts[i0]->charge(); + + fDxy_.get()[i0] = iParts[i0]->hwDxy(); + fEmID_.get()[i0] = iParts[i0]->hwEmID(); + fQuality_.get()[i0] = iParts[i0]->hwTkQuality(); + } + setNNVectorVar(); + return EvaluateNNFixed(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 96690c4ae3ef9..9aa36e60eac27 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -10,11 +10,14 @@ parser.add_argument("--dumpFilesOFF", help="switch on dump file production", action="store_true", default=False) parser.add_argument("--patternFilesOFF", help="switch on Layer-1 pattern file production", action="store_true", default=False) parser.add_argument("--serenity", help="use Serenity settigns as default everwhere, i.e. also for barrel", action="store_true", default=False) -parser.add_argument("--tm18", help="Add TM18 emulators", action="store_true", default=False) +parser.add_argument("--tm18", help="[DEPRECATED] Add TM18 emulators", action="store_true", default=False) parser.add_argument("--split18", help="Make 3 TM18 layer 1 pattern files", action="store_true", default=False) args = parser.parse_args() +if args.tm18: + print('[WARNING] CTL1@TM18 is now the default: --tm18 option is deprecated') + if args.dumpFilesOFF: print(f'Switching off dump file creation: dumpFilesOFF is {args.dumpFilesOFF}') if args.patternFilesOFF: @@ -144,17 +147,14 @@ ) process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() -process.l1tLayer1BarrelSerenity.regionizerAlgo = "MultififoBarrel" +process.l1tLayer1BarrelSerenity.regionizerAlgo = "MiddleBufferMultififo" process.l1tLayer1BarrelSerenity.regionizerAlgoParameters = cms.PSet( - barrelSetup = cms.string("Full54"), - useAlsoVtxCoords = cms.bool(True), - nClocks = cms.uint32(54), - nHCalLinks = cms.uint32(2), - nECalLinks = cms.uint32(1), nTrack = cms.uint32(22), nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), - nMu = cms.uint32(2)) + nMu = cms.uint32(2), + tmux6GCTinput = cms.bool(True), +) process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 process.l1tLayer1BarrelSerenity.pfAlgoParameters.nCalo = 15 @@ -169,18 +169,15 @@ phiSlices = cms.uint32(3), phiZero = cms.double(math.pi/18) ), - cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 0, 1.5), - phiSlices = cms.uint32(3), - phiZero = cms.double(math.pi*7/18) - ) - ) -# process.l1tLayer1BarrelSerenity.caloSectors = cms.VPSet( -# cms.PSet( -# etaBoundaries = cms.vdouble(-1.5, 1.5), -# phiSlices = cms.uint32(3), -# ) -# ) +) +process.l1tLayer1BarrelSerenity.boards = cms.VPSet(*[cms.PSet(regions = cms.vuint32(*range(18*i,18*i+18))) for i in range(3)]) +process.l1tLayer1BarrelSerenityElliptic = process.l1tLayer1BarrelSerenity.clone( + tkEgAlgoParameters = process.l1tLayer1BarrelSerenity.tkEgAlgoParameters.clone( + algorithm = 0, + trkQualityPtMin = 10.) +) + + if args.serenity: process.l1tLayer1.pfProducers[0] = "l1tLayer1BarrelSerenity" @@ -196,10 +193,12 @@ *barrelWriterDebugPFInConfigsAPx, *barrelWriterDebugPFOutConfigsAPx ) - process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(barrelSerenityVU9PPhi1Config,barrelSerenityVU13PPhi1Config) - process.l1tLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) - process.l1tLayer1HGCalElliptic.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) - process.l1tLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(*hgcalNoTKWriterConfigs) + process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) + process.l1tLayer1BarrelSerenityElliptic.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) + + process.l1tLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) + process.l1tLayer1HGCalElliptic.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) + process.l1tLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(hgcalNoTKOutputTM18WriterConfig) process.l1tLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) process.l1tSC4NGJetProducer.jets = cms.InputTag("l1tSC4PFL1PuppiEmulator") @@ -221,6 +220,7 @@ process.l1tLayer1Barrel + process.l1tLayer1BarrelTDR + process.l1tLayer1BarrelSerenity + + process.l1tLayer1BarrelSerenityElliptic + process.l1tLayer1HGCal + process.l1tLayer1HGCalElliptic + process.l1tLayer1HGCalNoTK + @@ -259,7 +259,7 @@ process.runPF.insert(process.runPF.index(process.l1tLayer2SeedConeJetWriter)+1, process.l1tLayer2SeedConeNGJetWriter) process.l1tLayer2SeedConeNGJetWriter.maxLinesPerFile = _eventsPerFile*54 if not args.dumpFilesOFF: - for det in "Barrel", "BarrelTDR", "BarrelSerenity", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": + for det in "Barrel", "BarrelTDR", "BarrelSerenity", "BarrelSerenityElliptic", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": l1pf = getattr(process, 'l1tLayer1'+det) l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") for det in "Barrel", "HGCal": @@ -267,81 +267,26 @@ l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+"Extended.dump") -if args.tm18: - process.l1tLayer1HGCalTM18 = process.l1tLayer1HGCal.clone() - process.l1tLayer1HGCalTM18.regionizerAlgo = "BufferedFoldedMultififo" - process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nClocks = 162 - process.l1tLayer1HGCalTM18.hgcalInputConversionParameters.emulateCorrections = True - del process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nEndcaps - del process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nTkLinks - del process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nCaloLinks - process.l1tLayer1HGCalNoTKTM18 = process.l1tLayer1HGCalNoTK.clone() - process.l1tLayer1HGCalNoTKTM18.regionizerAlgo = "BufferedFoldedMultififo" - process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nClocks = 162 - process.l1tLayer1HGCalNoTKTM18.hgcalInputConversionParameters.emulateCorrections = True - del process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nEndcaps - del process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nTkLinks - del process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nCaloLinks - process.l1tLayer1BarrelSerenityTM18 = process.l1tLayer1BarrelSerenity.clone() - process.l1tLayer1BarrelSerenityTM18.caloSectors = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 0, 1.5), - phiSlices = cms.uint32(3), - phiZero = cms.double(math.pi/18) - ), - ) - process.l1tLayer1BarrelSerenityTM18.regionizerAlgo = "MiddleBufferMultififo" - process.l1tLayer1BarrelSerenityTM18.regionizerAlgoParameters = cms.PSet( - nTrack = process.l1tLayer1BarrelSerenity.regionizerAlgoParameters.nTrack, - nCalo = process.l1tLayer1BarrelSerenity.regionizerAlgoParameters.nCalo, - nEmCalo = process.l1tLayer1BarrelSerenity.regionizerAlgoParameters.nEmCalo, - nMu = process.l1tLayer1BarrelSerenity.regionizerAlgoParameters.nMu, - tmux6GCTinput = cms.bool(True), - ) - process.l1tLayer1BarrelSerenityTM18.boards = cms.VPSet(*[cms.PSet(regions = cms.vuint32(*range(18*i,18*i+18))) for i in range(3)]) - - process.l1tLayer1BarrelSerenityEllipticTM18 = process.l1tLayer1BarrelSerenityTM18.clone( - tkEgAlgoParameters = process.l1tLayer1BarrelSerenityTM18.tkEgAlgoParameters.clone( - algorithm = 0, - trkQualityPtMin = 10.) - ) - - process.runPF.insert(process.runPF.index(process.l1tLayer1HGCal)+1, process.l1tLayer1HGCalTM18) - process.runPF.insert(process.runPF.index(process.l1tLayer1HGCalNoTK)+1, process.l1tLayer1HGCalNoTKTM18) - process.runPF.insert(process.runPF.index(process.l1tLayer1BarrelSerenity)+1, process.l1tLayer1BarrelSerenityTM18) - process.runPF.insert(process.runPF.index(process.l1tLayer1BarrelSerenity)+1, process.l1tLayer1BarrelSerenityEllipticTM18) - # FIXME: we need to schedule a new deregionizer for TM18 - process.runPF.insert(process.runPF.index(process.l1tLayer2EG)+1, process.l1tLayer2EGTM18) - if not args.patternFilesOFF: - process.l1tLayer1HGCalTM18.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) - process.l1tLayer1HGCalNoTKTM18.patternWriters = cms.untracked.VPSet(hgcalNoTKOutputTM18WriterConfig) - process.l1tLayer1BarrelSerenityTM18.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) - process.l1tLayer1BarrelSerenityEllipticTM18.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) - process.l1tLayer2EGTM18.writeInPattern = True - process.l1tLayer2EGTM18.writeOutPattern = True - if not args.dumpFilesOFF: - for det in "HGCalTM18", "HGCalNoTKTM18", "BarrelSerenityTM18", "BarrelSerenityEllipticTM18": - getattr(process, 'l1tLayer1'+det).dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") - if args.split18 and not args.patternFilesOFF: - from FWCore.Modules.preScaler_cfi import preScaler - for tmSlice, psOffset in (0,1), (6,2), (12,0): - setattr(process, f"preTM{tmSlice}", preScaler.clone(prescaleFactor = 3, prescaleOffset = psOffset)) - for det in "HGCalTM18", "HGCalNoTKTM18", "BarrelSerenityTM18": - tsmod = getattr(process, 'l1tLayer1'+det).clone() - tsmod.dumpFileName = cms.untracked.string("") - setattr(process, f"l1tLayer1{det}TS{tmSlice}", tsmod) - setattr(process, f"Write_{det}TS{tmSlice}", cms.Path(getattr(process, f"preTM{tmSlice}")+tsmod)) - getattr(process, f'l1tLayer1HGCalTM18TS{tmSlice}').patternWriters = cms.untracked.VPSet( - hgcalWriterOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18-outputs-ts{tmSlice}"), - hgcalWriterVU9PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu9p-ts{tmSlice}"), - hgcalWriterVU13PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu13p-ts{tmSlice}") - ) - getattr(process, f'l1tLayer1HGCalNoTKTM18TS{tmSlice}').patternWriters = cms.untracked.VPSet( - hgcalNoTKOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18-outputs-ts{tmSlice}"), - ) - getattr(process, f'l1tLayer1BarrelSerenityTM18TS{tmSlice}').patternWriters = cms.untracked.VPSet( - barrelSerenityOutputTM18WriterConfig.clone(outputFileName = f"l1BarrelSerenityTM18-outputs-ts{tmSlice}"), - barrelSerenityVU13PTM18WriterConfig.clone(inputFileName = f"l1BarrelSerenityTM18-inputs-vu13p-ts{tmSlice}") - ) +if args.split18 and not args.patternFilesOFF: + from FWCore.Modules.preScaler_cfi import preScaler + for tmSlice, psOffset in (0,1), (6,2), (12,0): + setattr(process, f"preTM{tmSlice}", preScaler.clone(prescaleFactor = 3, prescaleOffset = psOffset)) + for det in "HGCal", "HGCalNoTK", "BarrelSerenity": + tsmod = getattr(process, 'l1tLayer1'+det).clone() + tsmod.dumpFileName = cms.untracked.string("") + setattr(process, f"l1tLayer1{det}TS{tmSlice}", tsmod) + setattr(process, f"Write_{det}TS{tmSlice}", cms.Path(getattr(process, f"preTM{tmSlice}")+tsmod)) + getattr(process, f'l1tLayer1HGCalTS{tmSlice}').patternWriters = cms.untracked.VPSet( + hgcalWriterOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18-outputs-ts{tmSlice}"), + hgcalWriterVU9PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu9p-ts{tmSlice}"), + hgcalWriterVU13PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu13p-ts{tmSlice}") + ) + getattr(process, f'l1tLayer1HGCalNoTKTS{tmSlice}').patternWriters = cms.untracked.VPSet( + hgcalNoTKOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18-outputs-ts{tmSlice}"), + ) + getattr(process, f'l1tLayer1BarrelSerenityTS{tmSlice}').patternWriters = cms.untracked.VPSet( + barrelSerenityOutputTM18WriterConfig.clone(outputFileName = f"l1BarrelSerenityTM18-outputs-ts{tmSlice}"), + barrelSerenityVU13PTM18WriterConfig.clone(inputFileName = f"l1BarrelSerenityTM18-inputs-vu13p-ts{tmSlice}") + ) process.source.fileNames = [ '/store/cmst3/group/l1tr/FastPUPPI/14_2_X/fpinputs_140X/v0/TT_PU200/inputs140X_1.root' ]