From 30207b957df950692ba3f1a4c89fec537d8cee23 Mon Sep 17 00:00:00 2001 From: Henri Petrow <24872616+henripetrow@users.noreply.github.com> Date: Mon, 4 May 2026 17:24:37 +0300 Subject: [PATCH 01/92] L1TSC82ProngJetModel (#150) * Added nprong score to DataFormats. * Added L1TSC82ProngJet to DPGAnalysis. * Added L1TSC82ProngJetModel to L1Trigger/Phase2L1ParticleFlow * Fix for nprong tag. * Cleaned includes. * File renamed. * Removed comment from addPh2GTObjects(process) * fixes. * Reverted changes. * Removed cuts.. * Update L1Trigger/Phase2L1ParticleFlow/src/L1TSC82ProngJetID.cc Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update L1Trigger/Phase2L1ParticleFlow/plugins/L1TSC82ProngJetModelProducer.cc Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update DataFormats/L1TParticleFlow/src/jets.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * added values for minPt and maxEta. * Added std headers. * Added a check for fNParticles. * Update L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply CMSSW code-format --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../python/l1tPh2Nanotables_cff.py | 7 +- DataFormats/L1TParticleFlow/interface/jets.h | 6 +- DataFormats/L1TParticleFlow/src/jets.cpp | 6 +- .../interface/L1TSC82ProngJetID.h | 45 +++++ .../plugins/L1TSC82ProngJetModelProducer.cc | 108 ++++++++++++ .../python/l1pfJetMet_cff.py | 7 +- .../src/L1TSC82ProngJetID.cc | 154 ++++++++++++++++++ 7 files changed, 323 insertions(+), 10 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h create mode 100644 L1Trigger/Phase2L1ParticleFlow/plugins/L1TSC82ProngJetModelProducer.cc create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/L1TSC82ProngJetID.cc 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/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(); +} From 8f89e862dea265582a32d91d143f705302ed8414 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Thu, 30 Apr 2026 16:10:05 +0200 Subject: [PATCH 02/92] TM18 is now the default configuration for all serenity modules --- .../python/l1ctLayer1_cff.py | 14 +- .../python/l1ctLayer2EG_cff.py | 104 ++----------- .../test/make_l1ct_binaryFiles_cfg.py | 147 ++++++------------ 3 files changed, 61 insertions(+), 204 deletions(-) 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/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' ] From 1c4c42c4a5b04f441a2f746cdaba8b38e0d85405 Mon Sep 17 00:00:00 2001 From: Christopher Date: Tue, 5 May 2026 18:20:46 +0200 Subject: [PATCH 03/92] rebase NN vtx Emu to latest p2l1pfp --- .../L1TParticleFlow/interface/PFCandidate.h | 7 +- .../L1TParticleFlow/interface/datatypes.h | 1 + .../interface/layer1_emulator.h | 6 + .../L1TParticleFlow/src/classes_def.xml | 3 +- .../interface/NNVtxAssoc.h | 194 +++++++++++++++++- .../interface/puppi/linpuppi_ref.h | 51 ++--- .../plugins/L1TCorrelatorLayer1Producer.cc | 3 + .../python/l1ctLayer1_cff.py | 1 - .../python/mlAssociation_cfi.py | 5 +- .../Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 142 ++++++++----- .../src/puppi/linpuppi_ref.cpp | 170 ++++++++------- .../test/make_l1ct_binaryFiles_cfg.py | 13 +- 12 files changed, 409 insertions(+), 187 deletions(-) diff --git a/DataFormats/L1TParticleFlow/interface/PFCandidate.h b/DataFormats/L1TParticleFlow/interface/PFCandidate.h index ff6e026acdfa3..224665adb0ec9 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCandidate.h +++ b/DataFormats/L1TParticleFlow/interface/PFCandidate.h @@ -62,6 +62,9 @@ namespace l1t { uint16_t hwEmID() const { return hwEmID_; } uint64_t encodedPuppi64() const { return encodedPuppi64_; } + float hwAssociationScore() const { return hwAssociationScore_; } + void setHwAssociationScore(float score) { hwAssociationScore_ = score; } + void setHwZ0(int16_t hwZ0) { hwZ0_ = hwZ0; } void setHwDxy(int16_t hwDxy) { hwDxy_ = hwDxy; } void setHwTkQuality(uint16_t hwTkQuality) { hwTkQuality_ = hwTkQuality; } @@ -73,12 +76,14 @@ namespace l1t { L1CandPtr caloPtr_; PFTrackRef trackRef_; MuonRef muonRef_; - float dxy_, puppiWeight_, caloEta_, caloPhi_; + float dxy_, puppiWeight_, caloEta_, caloPhi_, hwAssociationScore_; int16_t hwZ0_, hwDxy_; uint16_t hwTkQuality_, hwPuppiWeight_, hwEmID_; uint64_t encodedPuppi64_; + int hwAssociation_; + void setPdgIdFromParticleType(int charge, ParticleType kind); }; diff --git a/DataFormats/L1TParticleFlow/interface/datatypes.h b/DataFormats/L1TParticleFlow/interface/datatypes.h index da8d053b04a86..88f09a5dcf663 100644 --- a/DataFormats/L1TParticleFlow/interface/datatypes.h +++ b/DataFormats/L1TParticleFlow/interface/datatypes.h @@ -22,6 +22,7 @@ namespace l1ct { typedef ap_int<10> z0_t; // 40cm / 0.1 typedef ap_uint<8> dxy_t; // sqrt(32)cm / 0.004 packed into 8 bit for l1ct typedef ap_uint<3> tkquality_t; // tbd + typedef ap_fixed<16, 6> nn_assoc_t; typedef ap_ufixed<9, 1, AP_RND_CONV, AP_WRAP> puppiWgt_t; typedef ap_uint<6> emid_t; typedef ap_uint<14> tk2em_dr_t; diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h index 22ae2df1758a9..a3967e318122b 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -126,6 +126,10 @@ namespace l1ct { const l1t::PFTrack *srcTrack = nullptr; const l1t::SAMuon *srcMu = nullptr; const l1t::PFCandidate *srcCand = nullptr; + + float AssociationScore; + int Association; + bool read(std::fstream &from); bool write(std::fstream &to) const; void clear() { @@ -134,6 +138,8 @@ namespace l1ct { srcTrack = nullptr; srcMu = nullptr; srcCand = nullptr; + AssociationScore = 0; + Association = 0; } inline void fill(const PFRegionEmu ®ion, const PFChargedObjEmu &src) { PuppiObj::fill(region, src); diff --git a/DataFormats/L1TParticleFlow/src/classes_def.xml b/DataFormats/L1TParticleFlow/src/classes_def.xml index e45d86590aa53..f8b2affdec60e 100644 --- a/DataFormats/L1TParticleFlow/src/classes_def.xml +++ b/DataFormats/L1TParticleFlow/src/classes_def.xml @@ -23,7 +23,8 @@ - + + diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h b/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h index 7c92ed343ab49..4d535041e0957 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h @@ -9,37 +9,209 @@ // Created: February 2025 #include +#include #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "ap_fixed.h" + +struct AssociationObjEmu { + l1ct::nn_assoc_t hwAssociationScore; + ap_uint<1> hwAssociation; +}; + +typedef ap_ufixed<22, 9> nn_inputtype; +typedef ap_fixed<22, 9> classtype; + +#define N_NN_ASSOC_FEATURES 4 // How many features are used in a track +#define N_NN_ASSOC_OUTPUTS 1 // How many features are used in a track + +static const nn_inputtype associationNetworkEtaBounds[127] = {0.0, + 0.01984126984126984, + 0.03968253968253968, + 0.05952380952380952, + 0.07936507936507936, + 0.0992063492063492, + 0.11904761904761904, + 0.1388888888888889, + 0.15873015873015872, + 0.17857142857142855, + 0.1984126984126984, + 0.21825396825396826, + 0.23809523809523808, + 0.2579365079365079, + 0.2777777777777778, + 0.2976190476190476, + 0.31746031746031744, + 0.33730158730158727, + 0.3571428571428571, + 0.376984126984127, + 0.3968253968253968, + 0.41666666666666663, + 0.4365079365079365, + 0.45634920634920634, + 0.47619047619047616, + 0.496031746031746, + 0.5158730158730158, + 0.5357142857142857, + 0.5555555555555556, + 0.5753968253968254, + 0.5952380952380952, + 0.615079365079365, + 0.6349206349206349, + 0.6547619047619048, + 0.6746031746031745, + 0.6944444444444444, + 0.7142857142857142, + 0.7341269841269841, + 0.753968253968254, + 0.7738095238095237, + 0.7936507936507936, + 0.8134920634920635, + 0.8333333333333333, + 0.8531746031746031, + 0.873015873015873, + 0.8928571428571428, + 0.9126984126984127, + 0.9325396825396824, + 0.9523809523809523, + 0.9722222222222222, + 0.992063492063492, + 1.0119047619047619, + 1.0317460317460316, + 1.0515873015873016, + 1.0714285714285714, + 1.0912698412698412, + 1.1111111111111112, + 1.130952380952381, + 1.1507936507936507, + 1.1706349206349205, + 1.1904761904761905, + 1.2103174603174602, + 1.23015873015873, + 1.25, + 1.2698412698412698, + 1.2896825396825395, + 1.3095238095238095, + 1.3293650793650793, + 1.349206349206349, + 1.369047619047619, + 1.3888888888888888, + 1.4087301587301586, + 1.4285714285714284, + 1.4484126984126984, + 1.4682539682539681, + 1.488095238095238, + 1.507936507936508, + 1.5277777777777777, + 1.5476190476190474, + 1.5674603174603174, + 1.5873015873015872, + 1.607142857142857, + 1.626984126984127, + 1.6468253968253967, + 1.6666666666666665, + 1.6865079365079365, + 1.7063492063492063, + 1.726190476190476, + 1.746031746031746, + 1.7658730158730158, + 1.7857142857142856, + 1.8055555555555554, + 1.8253968253968254, + 1.8452380952380951, + 1.865079365079365, + 1.8849206349206349, + 1.9047619047619047, + 1.9246031746031744, + 1.9444444444444444, + 1.9642857142857142, + 1.984126984126984, + 2.003968253968254, + 2.0238095238095237, + 2.0436507936507935, + 2.0634920634920633, + 2.083333333333333, + 2.1031746031746033, + 2.123015873015873, + 2.142857142857143, + 2.1626984126984126, + 2.1825396825396823, + 2.202380952380952, + 2.2222222222222223, + 2.242063492063492, + 2.261904761904762, + 2.2817460317460316, + 2.3015873015873014, + 2.321428571428571, + 2.341269841269841, + 2.361111111111111, + 2.380952380952381, + 2.4007936507936507, + 2.4206349206349205, + 2.4404761904761902, + 2.46031746031746, + 2.4801587301587302, + 2.5}; +static const nn_inputtype associationNetworkZ0ResBins[128] = { + 127.0, 126.0, 126.0, 126.0, 125.0, 124.0, 123.0, 122.0, 120.0, 119.0, 117.0, 115.0, 114.0, 112.0, 110.0, 107.0, + 105.0, 103.0, 101.0, 98.0, 96.0, 94.0, 91.0, 89.0, 87.0, 85.0, 82.0, 80.0, 78.0, 76.0, 74.0, 72.0, + 70.0, 68.0, 66.0, 64.0, 62.0, 61.0, 59.0, 57.0, 56.0, 54.0, 53.0, 51.0, 50.0, 48.0, 47.0, 46.0, + 45.0, 43.0, 42.0, 41.0, 40.0, 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 33.0, 32.0, 31.0, 30.0, + 30.0, 29.0, 28.0, 28.0, 27.0, 26.0, 26.0, 25.0, 24.0, 24.0, 23.0, 23.0, 22.0, 22.0, 21.0, 21.0, + 21.0, 20.0, 20.0, 19.0, 19.0, 18.0, 18.0, 18.0, 17.0, 17.0, 17.0, 16.0, 16.0, 16.0, 15.0, 15.0, + 15.0, 15.0, 14.0, 14.0, 14.0, 14.0, 13.0, 13.0, 13.0, 13.0, 12.0, 12.0, 12.0, 12.0, 12.0, 11.0, + 11.0, 11.0, 11.0, 11.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 9.0, 9.0, 9.0, 9.0, 9.0, 0.0}; +static const l1ct::z0_t associationNetworkZ0binning[3] = {-20.46912512, 20.46912512, 0.15991504}; + +#ifdef CMSSW_GIT_HASH +//HLS4ML compiled emulator modeling +#include "hls4ml/emulator.h" namespace edm { class ParameterSet; class ParameterSetDescription; } // namespace edm -namespace tensorflow { - class Session; -} // namespace tensorflow -using namespace l1ct; class NNVtxAssoc { public: - NNVtxAssoc(std::string AssociationGraphPath, + NNVtxAssoc(const std::shared_ptr model, const double AssociationThreshold, const std::vector& AssociationNetworkZ0binning, const std::vector& AssociationNetworkEtaBounds, - const std::vector& AssociationNetworkZ0ResBins); - + const std::vector& AssociationNetworkZ0ResBins, + bool debug); void NNVtxAssocDebug(); + static edm::ParameterSetDescription getParameterSetDescription(); - template - bool TTTrackNetworkSelector(const PFRegionEmu& region, const T& t, const l1ct::PVObjEmu& v); + void TTTrackNetworkSelector(const l1ct::PFRegionEmu& region, + const l1ct::TkObjEmu& t, + const l1ct::PVObjEmu& v, + l1ct::nn_assoc_t& score); + + l1ct::nn_assoc_t getAssociationThreshold() { return associationThreshold_; } private: - tensorflow::Session* associationSesh_; - double associationThreshold_; + nn_inputtype fPt_; + nn_inputtype fMVA_; + nn_inputtype fResBin_; + nn_inputtype fDz_; + + l1ct::nn_assoc_t associationThreshold_; + std::vector z0_binning_; std::vector eta_bins_; std::vector res_bins_; + + std::shared_ptr modelRef_; + std::stringstream log_; + + bool isDebugEnabled_; }; +#else + +void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_assoc_t& output_score); + #endif + +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h index 92f6eac0ae6c0..67385df0788fb 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h @@ -14,12 +14,6 @@ namespace edm { } // namespace edm namespace l1ct { -#ifdef CMSSW_GIT_HASH - const bool withinCMSSW_ = true; -#else - const bool withinCMSSW_ = false; -#endif - class LinPuppiEmulator { public: enum class SortAlgo { Insertion, BitonicRUFL, BitonicHLS, Hybrid, FoldedHybrid, BitonicVHDL }; @@ -44,10 +38,6 @@ namespace l1ct { pt_t ptCut, bool useMLAssociation = false, const double associationThreshold = 0.0, - std::string associationGraphPath = "", - std::vector associationNetworkZ0binning = {}, - std::vector associationNetworkEtaBounds = {}, - std::vector associationNetworkZ0ResBins = {}, unsigned int nFinalSort = 0, SortAlgo finalSortAlgo = SortAlgo::Insertion) : nTrack_(nTrack), @@ -70,18 +60,11 @@ namespace l1ct { priorPh_(1, priorPh), ptCut_(1, ptCut), useMLAssociation_(useMLAssociation), + associationThreshold_(associationThreshold), nFinalSort_(nFinalSort ? nFinalSort : nOut), finalSortAlgo_(finalSortAlgo), debug_(false), - fakePuppi_(false) { - if (useMLAssociation_ and withinCMSSW_) { - nnVtxAssoc_ = std::make_unique(NNVtxAssoc(associationGraphPath, - associationThreshold, - associationNetworkZ0binning, - associationNetworkEtaBounds, - associationNetworkZ0ResBins)); - } - } + fakePuppi_(false) {} LinPuppiEmulator(unsigned int nTrack, unsigned int nIn, @@ -114,10 +97,6 @@ namespace l1ct { pt_t ptCut_1, bool useMLAssociation = false, const double associationThreshold = 0.0, - std::string associationGraphPath = "", - std::vector associationNetworkZ0binning = {}, - std::vector associationNetworkEtaBounds = {}, - std::vector associationNetworkZ0ResBins = {}, unsigned int nFinalSort = 0, SortAlgo finalSortAlgo = SortAlgo::Insertion); @@ -142,10 +121,6 @@ namespace l1ct { const std::vector &ptCut, bool useMLAssociation, const double associationThreshold, - std::string associationGraphPath, - std::vector associationNetworkZ0binning, - std::vector associationNetworkEtaBounds, - std::vector associationNetworkZ0ResBins, unsigned int nFinalSort, SortAlgo finalSortAlgo) : nTrack_(nTrack), @@ -168,6 +143,7 @@ namespace l1ct { priorPh_(priorPh), ptCut_(ptCut), useMLAssociation_(useMLAssociation), + associationThreshold_(associationThreshold), nFinalSort_(nFinalSort), finalSortAlgo_(finalSortAlgo), debug_(false), @@ -181,10 +157,12 @@ namespace l1ct { void linpuppi_chs_ref(const PFRegionEmu ®ion, const PVObjEmu &pv, const std::vector &pfch /*[nTrack]*/, - std::vector &outallch /*[nTrack]*/) const; + std::vector &outallch /*[nTrack]*/, + std::vector &association /*[nTrack]*/) const; //vtx vetor void linpuppi_chs_ref(const PFRegionEmu ®ion, const std::vector &pv /*[nVtx]*/, + std::vector &association /*[nTrack]*/, const std::vector &pfch /*[nTrack]*/, std::vector &outallch /*[nTrack]*/) const; @@ -192,6 +170,7 @@ namespace l1ct { void linpuppi_flt(const PFRegionEmu ®ion, const std::vector &track /*[nTrack]*/, const std::vector &pv /*[nVtx]*/, + std::vector &association /*[nTrack]*/, const std::vector &pfallne /*[nIn]*/, std::vector &outallne_nocut /*[nIn]*/, std::vector &outallne /*[nIn]*/, @@ -199,6 +178,7 @@ namespace l1ct { void linpuppi_ref(const PFRegionEmu ®ion, const std::vector &track /*[nTrack]*/, const std::vector &pv /*[nVtx]*/, + std::vector &association /*[nTrack]*/, const std::vector &pfallne /*[nIn]*/, std::vector &outallne_nocut /*[nIn]*/, std::vector &outallne /*[nIn]*/, @@ -206,10 +186,11 @@ namespace l1ct { void linpuppi_ref(const PFRegionEmu ®ion, const std::vector &track /*[nTrack]*/, const std::vector &pv /*[nVtx]*/, + std::vector &association /*[nTrack]*/, const std::vector &pfallne /*[nIn]*/, std::vector &outselne /*[nOut]*/) const { std::vector outallne_nocut, outallne; - linpuppi_ref(region, track, pv, pfallne, outallne_nocut, outallne, outselne); + linpuppi_ref(region, track, pv, association, pfallne, outallne_nocut, outallne, outselne); } // neutrals, forward @@ -229,6 +210,10 @@ namespace l1ct { std::vector &out, SortAlgo algo = SortAlgo::Insertion); + void linpuppi_associate_trk(const PFRegionEmu ®ion, + const std::vector &trk /*[nTrack]*/, + const std::vector &pv /*[nVtx]*/, + std::vector &association) const; // for CMSSW void run(const PFInputRegion &in, const std::vector &pvs, OutputRegion &out) const; @@ -249,7 +234,13 @@ namespace l1ct { // NNVtx Association: bool useMLAssociation_; - std::unique_ptr nnVtxAssoc_; + float associationThreshold_ = 0; + + #ifdef CMSSW_GIT_HASH // NNVtx Association: + std::unique_ptr nnVtxAssoc_; + std::shared_ptr model; + hls4mlEmulator::ModelLoader loader; + #endif unsigned int nFinalSort_; // output after a full sort of charged + neutral SortAlgo finalSortAlgo_; diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 7f480cf5723df..b54b611885a10 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -1327,6 +1327,7 @@ std::unique_ptr L1TCorrelatorLayer1Producer::fetchPF ret->back().setHwTkQuality(p.hwTkQuality); ret->back().setCaloEta(reg.floatGlbEtaOf(p)); ret->back().setCaloPhi(reg.floatGlbPhiOf(p)); + ret->back().setHwAssociationScore(-1); // encode the PF candidate with the 64b encoding used for PUPPI l1ct::PuppiObj encodedPF; @@ -1391,9 +1392,11 @@ void L1TCorrelatorLayer1Producer::putPuppi(edm::Event &iEvent) const { coll->back().setHwZ0(p.hwZ0()); coll->back().setHwDxy(p.hwDxy()); coll->back().setHwTkQuality(p.hwTkQuality()); + coll->back().setHwAssociationScore(p.AssociationScore); } else { coll->back().setHwPuppiWeight(p.hwPuppiW()); coll->back().setHwEmID(p.hwEmID()); + coll->back().setHwAssociationScore(-1); } coll->back().setEncodedPuppi64(p.pack().to_uint64()); setRefs_(coll->back(), p); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 5c3a8e3543f37..ab743b30ebd5e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -1,5 +1,4 @@ import FWCore.ParameterSet.Config as cms - import math from L1Trigger.Phase2L1ParticleFlow.l1tPFTracksFromL1Tracks_cfi import l1tPFTracksFromL1Tracks, l1tPFTracksFromL1TracksExtended diff --git a/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py index af10c2ee9fade..706c49890d2cb 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py @@ -1,10 +1,11 @@ import FWCore.ParameterSet.Config as cms +import os from L1Trigger.VertexFinder.l1tVertexProducer_cfi import l1tVertexProducer # NNVertex Association Variables NNVtxAssociationPSet = cms.PSet( - associationThreshold = cms.double(0.1), #Association Network threshold for PV tracks - associationGraph = cms.string("L1Trigger/L1TTrackMatch/data/NNVtx_AssociationModelGraph.pb"), + associationThreshold = cms.double(-1.0), #Association Network threshold for PV tracks + associationNetworkPath = cms.string(os.environ["CMSSW_BASE"]+"/src/L1TNNVtx_Assoc_Model/L1TNNVtx_Assoc_Model_v0"), associationNetworkZ0binning = l1tVertexProducer.VertexReconstruction.FH_HistogramParameters, #Z0 binning used for setting the input feature digitisation associationNetworkEtaBounds = cms.vdouble(0.0, 0.01984126984126984, 0.03968253968253968, 0.05952380952380952, 0.07936507936507936, 0.0992063492063492, 0.11904761904761904, 0.1388888888888889, 0.15873015873015872, 0.17857142857142855, 0.1984126984126984, 0.21825396825396826, 0.23809523809523808, 0.2579365079365079, 0.2777777777777778, 0.2976190476190476, 0.31746031746031744, 0.33730158730158727, 0.3571428571428571, 0.376984126984127, 0.3968253968253968, 0.41666666666666663, 0.4365079365079365, 0.45634920634920634, 0.47619047619047616, 0.496031746031746, 0.5158730158730158, 0.5357142857142857, 0.5555555555555556, 0.5753968253968254, 0.5952380952380952, 0.615079365079365, 0.6349206349206349, 0.6547619047619048, 0.6746031746031745, 0.6944444444444444, 0.7142857142857142, 0.7341269841269841, 0.753968253968254, 0.7738095238095237, 0.7936507936507936, 0.8134920634920635, 0.8333333333333333, 0.8531746031746031, 0.873015873015873, 0.8928571428571428, 0.9126984126984127, 0.9325396825396824, 0.9523809523809523, 0.9722222222222222, 0.992063492063492, 1.0119047619047619, 1.0317460317460316, 1.0515873015873016, 1.0714285714285714, 1.0912698412698412, 1.1111111111111112, 1.130952380952381, 1.1507936507936507, 1.1706349206349205, 1.1904761904761905, 1.2103174603174602, 1.23015873015873, 1.25, 1.2698412698412698, 1.2896825396825395, 1.3095238095238095, 1.3293650793650793, 1.349206349206349, 1.369047619047619, 1.3888888888888888, 1.4087301587301586, 1.4285714285714284, 1.4484126984126984, 1.4682539682539681, 1.488095238095238, 1.507936507936508, 1.5277777777777777, 1.5476190476190474, 1.5674603174603174, 1.5873015873015872, 1.607142857142857, 1.626984126984127, 1.6468253968253967, 1.6666666666666665, 1.6865079365079365, 1.7063492063492063, 1.726190476190476, 1.746031746031746, 1.7658730158730158, 1.7857142857142856, 1.8055555555555554, 1.8253968253968254, 1.8452380952380951, 1.865079365079365, 1.8849206349206349, 1.9047619047619047, 1.9246031746031744, 1.9444444444444444, 1.9642857142857142, 1.984126984126984, 2.003968253968254, 2.0238095238095237, 2.0436507936507935, 2.0634920634920633, 2.083333333333333, 2.1031746031746033, 2.123015873015873, 2.142857142857143, 2.1626984126984126, 2.1825396825396823, 2.202380952380952, 2.2222222222222223, 2.242063492063492, 2.261904761904762, 2.2817460317460316, 2.3015873015873014, 2.321428571428571, 2.341269841269841, 2.361111111111111, 2.380952380952381, 2.4007936507936507, 2.4206349206349205, 2.4404761904761902, 2.46031746031746, 2.4801587301587302, 2.5), #Eta bounds used to set z0 resolution input feature associationNetworkZ0ResBins = cms.vdouble(127.0, 126.0, 126.0, 126.0, 125.0, 124.0, 123.0, 122.0, 120.0, 119.0, 117.0, 115.0, 114.0, 112.0, 110.0, 107.0, 105.0, 103.0, 101.0, 98.0, 96.0, 94.0, 91.0, 89.0, 87.0, 85.0, 82.0, 80.0, 78.0, 76.0, 74.0, 72.0, 70.0, 68.0, 66.0, 64.0, 62.0, 61.0, 59.0, 57.0, 56.0, 54.0, 53.0, 51.0, 50.0, 48.0, 47.0, 46.0, 45.0, 43.0, 42.0, 41.0, 40.0, 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 33.0, 32.0, 31.0, 30.0, 30.0, 29.0, 28.0, 28.0, 27.0, 26.0, 26.0, 25.0, 24.0, 24.0, 23.0, 23.0, 22.0, 22.0, 21.0, 21.0, 21.0, 20.0, 20.0, 19.0, 19.0, 18.0, 18.0, 18.0, 17.0, 17.0, 17.0, 16.0, 16.0, 16.0, 15.0, 15.0, 15.0, 15.0, 14.0, 14.0, 14.0, 14.0, 13.0, 13.0, 13.0, 13.0, 12.0, 12.0, 12.0, 12.0, 12.0, 11.0, 11.0, 11.0, 11.0, 11.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 9.0, 9.0, 9.0, 9.0, 9.0, 0.0), #z0 resolution input feature bins diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index 037b7a524b6d5..e6fc292b56324 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -6,81 +6,87 @@ // Created: February 2025 #include "L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h" + +#ifdef CMSSW_GIT_HASH #include "DataFormats/L1TParticleFlow/interface/PFTrack.h" -#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include #include -NNVtxAssoc::NNVtxAssoc(std::string AssociationGraphPath, +NNVtxAssoc::NNVtxAssoc(const std::shared_ptr model, const double AssociationThreshold, const std::vector& AssociationNetworkZ0binning, const std::vector& AssociationNetworkEtaBounds, - const std::vector& AssociationNetworkZ0ResBins) - : associationThreshold_(AssociationThreshold), + const std::vector& AssociationNetworkZ0ResBins, + bool debug) + : associationThreshold_((l1ct::nn_assoc_t)AssociationThreshold), z0_binning_(AssociationNetworkZ0binning), eta_bins_(AssociationNetworkEtaBounds), - res_bins_(AssociationNetworkZ0ResBins) { - tensorflow::GraphDef* associationGraph_ = tensorflow::loadGraphDef(AssociationGraphPath); - associationSesh_ = tensorflow::createSession(associationGraph_); + res_bins_(AssociationNetworkZ0ResBins), + modelRef_(model), + isDebugEnabled_(debug) { + fPt_ = 0; + fMVA_ = 0; + fResBin_ = 0; + fDz_ = 0; log_.setf(std::ios::fixed, std::ios::floatfield); log_.precision(3); } -template -bool NNVtxAssoc::TTTrackNetworkSelector(const PFRegionEmu& region, const T& t, const l1ct::PVObjEmu& v) { - tensorflow::Tensor inputAssoc(tensorflow::DT_FLOAT, {1, 4}); - std::vector outputAssoc; - - auto lower = std::lower_bound(eta_bins_.begin(), eta_bins_.end(), region.floatGlbEta(t.hwVtxEta())); +void NNVtxAssoc::TTTrackNetworkSelector(const l1ct::PFRegionEmu& region, + const l1ct::TkObjEmu& t, + const l1ct::PVObjEmu& v, + l1ct::nn_assoc_t& score) { + nn_inputtype modelInput[N_NN_ASSOC_FEATURES] = {}; // Do something + classtype classresult; - int resbin = std::distance(eta_bins_.begin(), lower); - float binWidth = z0_binning_[2]; - // Calculate integer dZ from track z0 and vertex z0 (use floating point version and convert internally allowing use of both emulator and simulator vertex and track) - float dZ = - abs(floor(((t.floatZ0() + z0_binning_[1]) / (binWidth))) - floor(((v.floatZ0() + z0_binning_[1]) / (binWidth)))); + int resbin = 0; + for (int ibin = 0; ibin <= 126; ++ibin) { + if ((t.hwEta > associationNetworkEtaBounds[ibin]) & (t.hwEta <= associationNetworkEtaBounds[ibin + 1])) { + resbin = ibin; + } + }; // The following constants <22, 9> are defined by the quantisation of the Neural Network - ap_ufixed<22, 9> ptEmulation_rescale = t.hwPt; - ap_ufixed<22, 9> resBinEmulation_rescale = res_bins_[resbin]; - ap_ufixed<22, 9> MVAEmulation_rescale = 0; - ap_ufixed<22, 9> dZEmulation_rescale = dZ; - - // Deal with this template class using 2 different objects (t) which have different calls to their PFTracks: - const l1t::PFTrack* srcTrack = nullptr; - if constexpr (std::is_same_v) - srcTrack = t.src; - else if constexpr (std::is_same_v) - srcTrack = t.srcTrack; - if (srcTrack) - MVAEmulation_rescale = srcTrack->trackWord().getMVAQualityBits(); - - inputAssoc.tensor()(0, 0) = ptEmulation_rescale.to_double(); - inputAssoc.tensor()(0, 1) = MVAEmulation_rescale.to_double(); - inputAssoc.tensor()(0, 2) = resBinEmulation_rescale.to_double() / 16.0; - inputAssoc.tensor()(0, 3) = dZEmulation_rescale.to_double(); - - // Run Association Network: - tensorflow::run(associationSesh_, {{"NNvtx_track_association:0", inputAssoc}}, {"Identity:0"}, &outputAssoc); - - double NNOutput = (double)outputAssoc[0].tensor()(0, 0); - double NNOutput_exp = 1.0 / (1.0 + exp(-1.0 * (NNOutput))); - - return NNOutput_exp >= associationThreshold_; + fPt_ = t.hwPt; + fResBin_ = associationNetworkZ0ResBins[resbin]; + fMVA_ = t.hwQuality; + fDz_ = t.hwZ0 - v.hwZ0; + + modelInput[0] = fPt_; // Obj pT + modelInput[1] = fMVA_; // Obj track quality + modelInput[2] = fResBin_ / 16; // Obj z0 resolution bin (rescaled) + modelInput[3] = fDz_; // Obj delta z from the PV + + modelRef_->prepare_input(modelInput); + modelRef_->predict(); + modelRef_->read_result(&classresult); + + score = (l1ct::nn_assoc_t)classresult; + + if (isDebugEnabled_) { + LogDebug("NNVtxAssoc") << "\n ===== Vertex Association Output Score =====" << std::endl; + } + float NNOutput_exp = 1.0 / (1.0 + exp(-1.0 * (classresult.to_float()))); + if (isDebugEnabled_) { + LogDebug("NNVtxAssoc") << "Score: " << classresult.to_float() << "exponentiated score " << NNOutput_exp + << std::endl; + } } -#ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" edm::ParameterSetDescription NNVtxAssoc::getParameterSetDescription() { edm::ParameterSetDescription description; description.add("associationThreshold"); - description.add("associationGraph"); + description.add("associationNetworkPath"); description.add>("associationNetworkZ0binning"); description.add>("associationNetworkEtaBounds"); description.add>("associationNetworkZ0ResBins"); return description; } -#endif void NNVtxAssoc::NNVtxAssocDebug() { log_ << "-- NNVtxAssocDebug --\n"; @@ -100,9 +106,39 @@ void NNVtxAssoc::NNVtxAssocDebug() { edm::LogPrint("NNVtxAssoc") << log_.str(); } -template bool NNVtxAssoc::TTTrackNetworkSelector(const PFRegionEmu&, - const l1ct::TkObjEmu&, - const l1ct::PVObjEmu&); -template bool NNVtxAssoc::TTTrackNetworkSelector(const PFRegionEmu&, - const l1ct::PFChargedObjEmu&, - const l1ct::PVObjEmu&); +#else + +#include "L1TNNVtx_Assoc_Model/L1TNNVtx_Assoc_Model_v0/NN/L1TNNVtx_Assoc_Model_v0.h" + +void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_assoc_t& output_score) { + int resbin = 0; + l1ct::eta_t temp_hwEta; + if (t.hwEta < 0) { + temp_hwEta = -1 * t.hwEta; + } + for (int ibin = 0; ibin <= 126; ++ibin) { + if (temp_hwEta > l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin]) & + temp_hwEta <= l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin + 1])) { + resbin = ibin; + break; + } + }; + // The following constants <22, 9> are defined by the quantisation of the Neural Network + nn_inputtype fPt_ = t.hwPt; + nn_inputtype fResBin_ = associationNetworkZ0ResBins[resbin]; + nn_inputtype fMVA_ = t.hwQuality; + nn_inputtype fDz_ = t.hwZ0 - v.hwZ0; + + nn_inputtype association_input[N_NN_ASSOC_FEATURES]; + L1TNNVtx_Assoc_Model_v0::result_t nn_output_score[N_NN_ASSOC_OUTPUTS]; + + association_input[0] = fPt_; // Obj pT + association_input[1] = fMVA_; // Obj track quality + association_input[2] = fResBin_ / 16; // Obj z0 resolution bin (rescaled) + association_input[3] = fDz_; // Obj delta z from the PV + + L1TNNVtx_Assoc_Model_v0::NNvtx_assoc(association_input, nn_output_score); + + output_score = (l1ct::nn_assoc_t)nn_output_score[0]; +} +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp index a38e4fdda8769..096b5f5a82b4c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp @@ -14,9 +14,9 @@ #include "FWCore/Utilities/interface/transform.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/ParameterSet/interface/FileInPath.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h" #endif -#include "L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h" using namespace l1ct; using namespace linpuppi; @@ -52,10 +52,6 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(unsigned int nTrack, pt_t ptCut_1, bool useMLAssociation, const double associationThreshold, - std::string associationGraphPath, - std::vector associationNetworkZ0binning, - std::vector associationNetworkEtaBounds, - std::vector associationNetworkZ0ResBins, unsigned int nFinalSort, SortAlgo finalSortAlgo) : nTrack_(nTrack), @@ -78,6 +74,7 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(unsigned int nTrack, priorPh_(2), ptCut_(2), useMLAssociation_(useMLAssociation), + associationThreshold_(associationThreshold), nFinalSort_(nFinalSort ? nFinalSort : nOut), finalSortAlgo_(finalSortAlgo), debug_(false), @@ -102,14 +99,6 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(unsigned int nTrack, priorPh_[1] = priorPh_1; ptCut_[0] = ptCut_0; ptCut_[1] = ptCut_1; - - if (useMLAssociation_ and withinCMSSW_) { - nnVtxAssoc_ = std::make_unique(NNVtxAssoc(associationGraphPath, - associationThreshold, - associationNetworkZ0binning, - associationNetworkEtaBounds, - associationNetworkZ0ResBins)); - } } #ifdef CMSSW_GIT_HASH @@ -135,6 +124,8 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(const edm::ParameterSet &iConfig) priorPh_(iConfig.getParameter>("priorsPhoton")), ptCut_(edm::vector_transform(iConfig.getParameter>("ptCut"), l1ct::Scales::makePtFromFloat)), useMLAssociation_(iConfig.getParameter("useMLAssociation")), + loader(hls4mlEmulator::ModelLoader(iConfig.getParameter("NNVtxAssociation") + .getParameter("associationNetworkPath"))), nFinalSort_(iConfig.getParameter("nFinalSort")), debug_(iConfig.getUntrackedParameter("debug", false)), fakePuppi_(iConfig.getParameter("fakePuppi")) { @@ -160,15 +151,19 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(const edm::ParameterSet &iConfig) throw cms::Exception("Configuration", "size mismatch for ptCut parameter"); if (useMLAssociation_) { edm::ParameterSet nnVtxAssocPSet_ = iConfig.getParameter("NNVtxAssociation"); - edm::FileInPath associationGraphPathFIP = - edm::FileInPath(nnVtxAssocPSet_.getParameter("associationGraph")); - - nnVtxAssoc_ = std::make_unique( - NNVtxAssoc(associationGraphPathFIP.fullPath(), - nnVtxAssocPSet_.getParameter("associationThreshold"), - nnVtxAssocPSet_.getParameter>("associationNetworkZ0binning"), - nnVtxAssocPSet_.getParameter>("associationNetworkEtaBounds"), - nnVtxAssocPSet_.getParameter>("associationNetworkZ0ResBins"))); + try { + model = loader.load_model(); + nnVtxAssoc_ = std::make_unique( + NNVtxAssoc(model, + nnVtxAssocPSet_.getParameter("associationThreshold"), + nnVtxAssocPSet_.getParameter>("associationNetworkZ0binning"), + nnVtxAssocPSet_.getParameter>("associationNetworkEtaBounds"), + nnVtxAssocPSet_.getParameter>("associationNetworkZ0ResBins"), + debug_)); + } catch (std::runtime_error &e) { + throw cms::Exception("ModelError") << " ERROR: failed to load L1TNNVtxAssoc model version \"" + << "\". Model version not found in cms-hls4ml externals."; + } } const std::string &sortAlgo = iConfig.getParameter("finalSortAlgo"); if (sortAlgo == "Insertion") @@ -274,55 +269,49 @@ void l1ct::LinPuppiEmulator::puppisort_and_crop_ref(unsigned int nOutMax, void l1ct::LinPuppiEmulator::linpuppi_chs_ref(const PFRegionEmu ®ion, const std::vector &pv, + std::vector &association /*[nTrack]*/, const std::vector &pfch /*[nTrack]*/, std::vector &outallch /*[nTrack]*/) const { const unsigned int nTrack = std::min(nTrack_, pfch.size()); - const unsigned int nVtx = std::min(nVtx_, pv.size()); outallch.resize(nTrack); for (unsigned int i = 0; i < nTrack; ++i) { - int pZ0 = pfch[i].hwZ0; - int z0diff = -99999; - bool pass_network = false; - for (unsigned int j = 0; j < nVtx; ++j) { - int pZ0Diff = pZ0 - pv[j].hwZ0; - if (std::abs(z0diff) > std::abs(pZ0Diff)) - z0diff = pZ0Diff; - if (useMLAssociation_ and withinCMSSW_ && - nnVtxAssoc_->TTTrackNetworkSelector(region, pfch[i], pv[j]) == 1) - pass_network = true; - } + bool accept = pfch[i].hwPt != 0; - if (!fakePuppi_ && !useMLAssociation_) - accept = accept && region.isFiducial(pfch[i]) && (std::abs(z0diff) <= int(dzCut_) || pfch[i].hwId.isMuon()); - if (!fakePuppi_ && useMLAssociation_) - accept = accept && region.isFiducial(pfch[i]) && (pass_network || pfch[i].hwId.isMuon()); + if (!fakePuppi_) + accept = accept && region.isFiducial(pfch[i]) && (association[i].hwAssociation == 1 || pfch[i].hwId.isMuon()); if (accept) { outallch[i].fill(region, pfch[i]); + outallch[i].Association = association[i].hwAssociation; + outallch[i].AssociationScore = association[i].hwAssociationScore; if (fakePuppi_) { // overwrite Dxy & TkQuality with debug information outallch[i].setHwDxy(dxy_t(pv[0].hwZ0)); ///hack to get this to work outallch[i].setHwTkQuality(region.isFiducial(pfch[i]) ? 1 : 0); } if (debug_ && pfch[i].hwPt > 0) - dbgPrintf("ref candidate %02u pt %7.2f pid %1d vz %+6d dz %+6d (cut %5d), fid %1d -> pass, packed %s\n", - i, - pfch[i].floatPt(), - pfch[i].intId(), - int(pfch[i].hwZ0), - z0diff, - dzCut_, - region.isFiducial(pfch[i]), - outallch[i].pack().to_string(16).c_str()); + dbgPrintf( + "ref candidate %02u pt %7.2f pid %1d, z0 %7d, associated %1d, association score %10.6f, fid %1d -> pass, " + "packed %s\n", + i, + pfch[i].floatPt(), + pfch[i].intId(), + int(pfch[i].hwZ0), + int(association[i].hwAssociation), + association[i].hwAssociationScore.to_float(), + region.isFiducial(pfch[i]), + outallch[i].pack().to_string(16).c_str()); } else { outallch[i].clear(); if (debug_ && pfch[i].hwPt > 0) - dbgPrintf("ref candidate %02u pt %7.2f pid %1d vz %+6d dz %+6d (cut %5d), fid %1d -> fail\n", - i, - pfch[i].floatPt(), - pfch[i].intId(), - int(pfch[i].hwZ0), - z0diff, - dzCut_, - region.isFiducial(pfch[i])); + dbgPrintf( + "ref candidate %02u pt %7.2f pid %1d , z0 %7d, associated %1d, association score %10.6f, fid %1d -> " + "fail\n", + i, + pfch[i].floatPt(), + pfch[i].intId(), + int(pfch[i].hwZ0), + int(association[i].hwAssociation), + association[i].hwAssociationScore.to_float(), + region.isFiducial(pfch[i])); } } } @@ -465,9 +454,41 @@ void l1ct::LinPuppiEmulator::fwdlinpuppi_ref(const PFRegionEmu ®ion, puppisort_and_crop_ref(nOut_, outallne, outselne); } +void l1ct::LinPuppiEmulator::linpuppi_associate_trk(const PFRegionEmu ®ion, + const std::vector &trk, + const std::vector &pv, + std::vector &Associations) const { + const unsigned int nTrack = trk.size(); + const unsigned int nVtx_ = pv.size(); + Associations.clear(); + nn_assoc_t nnvtx_score = 0; + nn_assoc_t associationThreshold = associationThreshold_; + AssociationObjEmu association; + for (unsigned int it = 0; it < nTrack; ++it) { + for (unsigned int v = 0; v < nVtx_; ++v) { + if (useMLAssociation_) { +#ifdef CMSSW_GIT_HASH + nnVtxAssoc_->TTTrackNetworkSelector(region, trk[it], pv[v], nnvtx_score); + associationThreshold = nnVtxAssoc_->getAssociationThreshold(); +#else + EmuNetworkSelector(trk[it], pv[v], nnvtx_score); +#endif + } else { + nnvtx_score = + (std::abs(int(trk[it].hwZ0) - int(pv[v].hwZ0)) <= int(dzCut_)) ? nn_assoc_t(1.0) : nn_assoc_t(0.0); + } + + association.hwAssociationScore = nnvtx_score; + association.hwAssociation = (nnvtx_score > associationThreshold) ? 1 : 0; + Associations.push_back(association); + } + } +} + void l1ct::LinPuppiEmulator::linpuppi_ref(const PFRegionEmu ®ion, const std::vector &track /*[nTrack]*/, const std::vector &pv, /*[nVtx]*/ + std::vector &association /*[nTrack]*/, const std::vector &pfallne /*[nIn]*/, std::vector &outallne_nocut /*[nIn]*/, std::vector &outallne /*[nIn]*/, @@ -487,22 +508,7 @@ void l1ct::LinPuppiEmulator::linpuppi_ref(const PFRegionEmu ®ion, for (unsigned int it = 0; it < nTrack; ++it) { if (track[it].hwPt == 0) continue; - - int pZMin = 99999; - bool pass_network = false; - for (unsigned int v = 0; v < nVtx_; ++v) { - if (v < pv.size()) { - int ppZMin = std::abs(int(track[it].hwZ0 - pv[v].hwZ0)); - if (pZMin > ppZMin) - pZMin = ppZMin; - if (useMLAssociation_ and withinCMSSW_ && - nnVtxAssoc_->TTTrackNetworkSelector(region, track[it], pv[v]) == 1) - pass_network = true; - } - } - if (useMLAssociation_ && !pass_network) - continue; - if (!useMLAssociation_ && std::abs(pZMin) > int(dzCut_)) + if (association[it].hwAssociation != 1) continue; unsigned int dr2 = dr2_int(pfallne[in].hwEta, pfallne[in].hwPhi, track[it].hwEta, track[it].hwPhi); if (dr2 <= dR2Max_) { // if dr is inside puppi cone @@ -624,6 +630,7 @@ void l1ct::LinPuppiEmulator::fwdlinpuppi_flt(const PFRegionEmu ®ion, void l1ct::LinPuppiEmulator::linpuppi_flt(const PFRegionEmu ®ion, const std::vector &track /*[nTrack]*/, const std::vector &pv, + std::vector &association /*[nTrack]*/, const std::vector &pfallne /*[nIn]*/, std::vector &outallne_nocut /*[nIn]*/, std::vector &outallne /*[nIn]*/, @@ -643,20 +650,7 @@ void l1ct::LinPuppiEmulator::linpuppi_flt(const PFRegionEmu ®ion, for (unsigned int it = 0; it < nTrack; ++it) { if (track[it].hwPt == 0) continue; - - int pZMin = 99999; - bool pass_network = false; - for (unsigned int v = 0, nVtx = std::min(nVtx_, pv.size()); v < nVtx; ++v) { - int ppZMin = std::abs(int(track[it].hwZ0 - pv[v].hwZ0)); - if (pZMin > ppZMin) - pZMin = ppZMin; - if (useMLAssociation_ and withinCMSSW_ && - nnVtxAssoc_->TTTrackNetworkSelector(region, track[it], pv[v]) == 1) - pass_network = true; - } - if (useMLAssociation_ && !pass_network) - continue; - if (!useMLAssociation_ && std::abs(pZMin) > int(dzCut_)) + if (association[it].hwAssociation != 1) continue; unsigned int dr2 = dr2_int( pfallne[in].hwEta, pfallne[in].hwPhi, track[it].hwEta, track[it].hwPhi); // if dr is inside puppi cone @@ -687,8 +681,10 @@ void l1ct::LinPuppiEmulator::run(const PFInputRegion &in, } if (std::abs(in.region.floatEtaCenter()) < 2.5) { // within tracker std::vector outallch, outallne_nocut, outallne, outselne; - linpuppi_chs_ref(in.region, pvs, out.pfcharged, outallch); - linpuppi_ref(in.region, in.track, pvs, out.pfneutral, outallne_nocut, outallne, outselne); + std::vector associations; + linpuppi_associate_trk(in.region, in.track, pvs, associations); + linpuppi_chs_ref(in.region, pvs, associations, out.pfcharged, outallch); + linpuppi_ref(in.region, in.track, pvs, associations, out.pfneutral, outallne_nocut, outallne, outselne); // ensure proper sizes of the vectors, to get accurate sorting wrt firmware const std::vector &ne = (nOut_ == nIn_ ? outallne : outselne); unsigned int nch = outallch.size(), nne = ne.size(), i; diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 9aa36e60eac27..d4456abf87bb7 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -61,6 +61,7 @@ process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') process.load('L1Trigger.Phase2L1ParticleFlow.l1pfJetMet_cff') +process.load('L1Trigger.Phase2L1ParticleFlow.mlAssociation_cfi') process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') process.l1tTrackSelectionProducer.processSimulatedTracks = False # these would need stubs, and are not used anyway @@ -177,6 +178,11 @@ trkQualityPtMin = 10.) ) +process.l1tLayer1HGCalNNAssoc = process.l1tLayer1HGCal.clone() +associationPSset = process.NNVtxAssociationPSet.clone() +associationPSset.associationThreshold = cms.double(-1.0) +process.l1tLayer1HGCalNNAssoc.puAlgoParameters.useMLAssociation = True +process.l1tLayer1HGCalNNAssoc.puAlgoParameters.NNVtxAssociation = associationPSset if args.serenity: @@ -200,6 +206,7 @@ process.l1tLayer1HGCalElliptic.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) process.l1tLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(hgcalNoTKOutputTM18WriterConfig) process.l1tLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) + process.l1tLayer1HGCalNNAssoc.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) process.l1tSC4NGJetProducer.jets = cms.InputTag("l1tSC4PFL1PuppiEmulator") process.l1tSC4NGJetProducer.doJEC = cms.bool(True) @@ -259,7 +266,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", "BarrelSerenityElliptic", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": + for det in "Barrel", "BarrelTDR", "BarrelSerenity", "BarrelSerenityElliptic", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF","HGCalNNAssoc": l1pf = getattr(process, 'l1tLayer1'+det) l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") for det in "Barrel", "HGCal": @@ -281,6 +288,10 @@ hgcalWriterVU9PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu9p-ts{tmSlice}"), hgcalWriterVU13PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18-inputs-vu13p-ts{tmSlice}") ) + getattr(process, f'l1tLayer1HGCalTM18NNAssocTS{tmSlice}').patternWriters = cms.untracked.VPSet( + hgcalWriterOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18NN-outputs-ts{tmSlice}"), + hgcalWriterVU13PTM18WriterConfig.clone(inputFileName = f"l1HGCalTM18NN-inputs-vu13p-ts{tmSlice}") + ) getattr(process, f'l1tLayer1HGCalNoTKTS{tmSlice}').patternWriters = cms.untracked.VPSet( hgcalNoTKOutputTM18WriterConfig.clone(outputFileName = f"l1HGCalTM18-outputs-ts{tmSlice}"), ) From 91e2644d426c657f97e3efecfabc721caf8d1e1a Mon Sep 17 00:00:00 2001 From: Christopher Date: Tue, 5 May 2026 21:25:34 +0200 Subject: [PATCH 04/92] Format changes --- .../interface/puppi/linpuppi_ref.h | 10 +++++----- .../Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h index 67385df0788fb..09423c975586a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h @@ -236,11 +236,11 @@ namespace l1ct { bool useMLAssociation_; float associationThreshold_ = 0; - #ifdef CMSSW_GIT_HASH // NNVtx Association: - std::unique_ptr nnVtxAssoc_; - std::shared_ptr model; - hls4mlEmulator::ModelLoader loader; - #endif +#ifdef CMSSW_GIT_HASH // NNVtx Association: + std::unique_ptr nnVtxAssoc_; + std::shared_ptr model; + hls4mlEmulator::ModelLoader loader; +#endif unsigned int nFinalSort_; // output after a full sort of charged + neutral SortAlgo finalSortAlgo_; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp index 096b5f5a82b4c..8aeac8c62af60 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp @@ -17,7 +17,6 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h" #endif - using namespace l1ct; using namespace linpuppi; @@ -275,7 +274,6 @@ void l1ct::LinPuppiEmulator::linpuppi_chs_ref(const PFRegionEmu ®ion, const unsigned int nTrack = std::min(nTrack_, pfch.size()); outallch.resize(nTrack); for (unsigned int i = 0; i < nTrack; ++i) { - bool accept = pfch[i].hwPt != 0; if (!fakePuppi_) accept = accept && region.isFiducial(pfch[i]) && (association[i].hwAssociation == 1 || pfch[i].hwId.isMuon()); From 1c28e9c711d9450a171acd4bd45b5e28923c3ab1 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Fri, 5 Jun 2026 13:58:05 +0200 Subject: [PATCH 05/92] Apply suggestion for printing model name from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp index 8aeac8c62af60..7a1c39ae7c0cd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp @@ -160,8 +160,9 @@ l1ct::LinPuppiEmulator::LinPuppiEmulator(const edm::ParameterSet &iConfig) nnVtxAssocPSet_.getParameter>("associationNetworkZ0ResBins"), debug_)); } catch (std::runtime_error &e) { - throw cms::Exception("ModelError") << " ERROR: failed to load L1TNNVtxAssoc model version \"" - << "\". Model version not found in cms-hls4ml externals."; + throw cms::Exception("ModelError") << "Failed to load L1TNNVtxAssoc model from \"" + << nnVtxAssocPSet_.getParameter("associationNetworkPath") + << "\": " << e.what(); } } const std::string &sortAlgo = iConfig.getParameter("finalSortAlgo"); From 67521910918e2c5c86464682a9fedda9d5ce3656 Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 5 Jun 2026 14:18:17 +0200 Subject: [PATCH 06/92] first copilot comments --- DataFormats/L1TParticleFlow/interface/PFCandidate.h | 2 -- DataFormats/L1TParticleFlow/src/classes_def.xml | 5 +++-- L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/DataFormats/L1TParticleFlow/interface/PFCandidate.h b/DataFormats/L1TParticleFlow/interface/PFCandidate.h index 224665adb0ec9..b029ca99c3abd 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCandidate.h +++ b/DataFormats/L1TParticleFlow/interface/PFCandidate.h @@ -82,8 +82,6 @@ namespace l1t { uint16_t hwTkQuality_, hwPuppiWeight_, hwEmID_; uint64_t encodedPuppi64_; - int hwAssociation_; - void setPdgIdFromParticleType(int charge, ParticleType kind); }; diff --git a/DataFormats/L1TParticleFlow/src/classes_def.xml b/DataFormats/L1TParticleFlow/src/classes_def.xml index f8b2affdec60e..326dbfeceef42 100644 --- a/DataFormats/L1TParticleFlow/src/classes_def.xml +++ b/DataFormats/L1TParticleFlow/src/classes_def.xml @@ -23,8 +23,9 @@ - - + + + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py index 706c49890d2cb..46d0b46a64722 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/mlAssociation_cfi.py @@ -5,7 +5,7 @@ # NNVertex Association Variables NNVtxAssociationPSet = cms.PSet( associationThreshold = cms.double(-1.0), #Association Network threshold for PV tracks - associationNetworkPath = cms.string(os.environ["CMSSW_BASE"]+"/src/L1TNNVtx_Assoc_Model/L1TNNVtx_Assoc_Model_v0"), + associationNetworkPath = cms.string(os.environ["CMSSW_BASE"]+"/src/NNVtx/L1TNNVtx_Assoc_Model_v0"), associationNetworkZ0binning = l1tVertexProducer.VertexReconstruction.FH_HistogramParameters, #Z0 binning used for setting the input feature digitisation associationNetworkEtaBounds = cms.vdouble(0.0, 0.01984126984126984, 0.03968253968253968, 0.05952380952380952, 0.07936507936507936, 0.0992063492063492, 0.11904761904761904, 0.1388888888888889, 0.15873015873015872, 0.17857142857142855, 0.1984126984126984, 0.21825396825396826, 0.23809523809523808, 0.2579365079365079, 0.2777777777777778, 0.2976190476190476, 0.31746031746031744, 0.33730158730158727, 0.3571428571428571, 0.376984126984127, 0.3968253968253968, 0.41666666666666663, 0.4365079365079365, 0.45634920634920634, 0.47619047619047616, 0.496031746031746, 0.5158730158730158, 0.5357142857142857, 0.5555555555555556, 0.5753968253968254, 0.5952380952380952, 0.615079365079365, 0.6349206349206349, 0.6547619047619048, 0.6746031746031745, 0.6944444444444444, 0.7142857142857142, 0.7341269841269841, 0.753968253968254, 0.7738095238095237, 0.7936507936507936, 0.8134920634920635, 0.8333333333333333, 0.8531746031746031, 0.873015873015873, 0.8928571428571428, 0.9126984126984127, 0.9325396825396824, 0.9523809523809523, 0.9722222222222222, 0.992063492063492, 1.0119047619047619, 1.0317460317460316, 1.0515873015873016, 1.0714285714285714, 1.0912698412698412, 1.1111111111111112, 1.130952380952381, 1.1507936507936507, 1.1706349206349205, 1.1904761904761905, 1.2103174603174602, 1.23015873015873, 1.25, 1.2698412698412698, 1.2896825396825395, 1.3095238095238095, 1.3293650793650793, 1.349206349206349, 1.369047619047619, 1.3888888888888888, 1.4087301587301586, 1.4285714285714284, 1.4484126984126984, 1.4682539682539681, 1.488095238095238, 1.507936507936508, 1.5277777777777777, 1.5476190476190474, 1.5674603174603174, 1.5873015873015872, 1.607142857142857, 1.626984126984127, 1.6468253968253967, 1.6666666666666665, 1.6865079365079365, 1.7063492063492063, 1.726190476190476, 1.746031746031746, 1.7658730158730158, 1.7857142857142856, 1.8055555555555554, 1.8253968253968254, 1.8452380952380951, 1.865079365079365, 1.8849206349206349, 1.9047619047619047, 1.9246031746031744, 1.9444444444444444, 1.9642857142857142, 1.984126984126984, 2.003968253968254, 2.0238095238095237, 2.0436507936507935, 2.0634920634920633, 2.083333333333333, 2.1031746031746033, 2.123015873015873, 2.142857142857143, 2.1626984126984126, 2.1825396825396823, 2.202380952380952, 2.2222222222222223, 2.242063492063492, 2.261904761904762, 2.2817460317460316, 2.3015873015873014, 2.321428571428571, 2.341269841269841, 2.361111111111111, 2.380952380952381, 2.4007936507936507, 2.4206349206349205, 2.4404761904761902, 2.46031746031746, 2.4801587301587302, 2.5), #Eta bounds used to set z0 resolution input feature associationNetworkZ0ResBins = cms.vdouble(127.0, 126.0, 126.0, 126.0, 125.0, 124.0, 123.0, 122.0, 120.0, 119.0, 117.0, 115.0, 114.0, 112.0, 110.0, 107.0, 105.0, 103.0, 101.0, 98.0, 96.0, 94.0, 91.0, 89.0, 87.0, 85.0, 82.0, 80.0, 78.0, 76.0, 74.0, 72.0, 70.0, 68.0, 66.0, 64.0, 62.0, 61.0, 59.0, 57.0, 56.0, 54.0, 53.0, 51.0, 50.0, 48.0, 47.0, 46.0, 45.0, 43.0, 42.0, 41.0, 40.0, 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 33.0, 32.0, 31.0, 30.0, 30.0, 29.0, 28.0, 28.0, 27.0, 26.0, 26.0, 25.0, 24.0, 24.0, 23.0, 23.0, 22.0, 22.0, 21.0, 21.0, 21.0, 20.0, 20.0, 19.0, 19.0, 18.0, 18.0, 18.0, 17.0, 17.0, 17.0, 16.0, 16.0, 16.0, 15.0, 15.0, 15.0, 15.0, 14.0, 14.0, 14.0, 14.0, 13.0, 13.0, 13.0, 13.0, 12.0, 12.0, 12.0, 12.0, 12.0, 11.0, 11.0, 11.0, 11.0, 11.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 9.0, 9.0, 9.0, 9.0, 9.0, 0.0), #z0 resolution input feature bins From f9bf6f6a65065acad2ec81f6cd6bfa64544a588f Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 5 Jun 2026 14:53:29 +0200 Subject: [PATCH 07/92] remove magic number bin iteration --- .../Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index e6fc292b56324..e979bbafeb2f5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -42,11 +42,18 @@ void NNVtxAssoc::TTTrackNetworkSelector(const l1ct::PFRegionEmu& region, classtype classresult; int resbin = 0; - for (int ibin = 0; ibin <= 126; ++ibin) { - if ((t.hwEta > associationNetworkEtaBounds[ibin]) & (t.hwEta <= associationNetworkEtaBounds[ibin + 1])) { + int Nresbins = std::size(associationNetworkEtaBounds); + + l1ct::eta_t temp_hwEta = t.hwEta; + if (temp_hwEta < 0) + temp_hwEta = -temp_hwEta; + for (int ibin = 0; ibin < Nresbins; ++ibin) { + if (temp_hwEta > l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin]) && + temp_hwEta <= l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin + 1])) { resbin = ibin; + break; } - }; + } // The following constants <22, 9> are defined by the quantisation of the Neural Network fPt_ = t.hwPt; @@ -112,17 +119,17 @@ void NNVtxAssoc::NNVtxAssocDebug() { void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_assoc_t& output_score) { int resbin = 0; - l1ct::eta_t temp_hwEta; - if (t.hwEta < 0) { - temp_hwEta = -1 * t.hwEta; - } - for (int ibin = 0; ibin <= 126; ++ibin) { - if (temp_hwEta > l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin]) & + int Nresbins = std::size(associationNetworkEtaBounds); + l1ct::eta_t temp_hwEta = t.hwEta; + if (temp_hwEta < 0) + temp_hwEta = -temp_hwEta; + for (int ibin = 0; ibin < Nresbins; ++ibin) { + if (temp_hwEta > l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin]) && temp_hwEta <= l1ct::Scales::makeEta(associationNetworkEtaBounds[ibin + 1])) { resbin = ibin; break; } - }; + } // The following constants <22, 9> are defined by the quantisation of the Neural Network nn_inputtype fPt_ = t.hwPt; nn_inputtype fResBin_ = associationNetworkZ0ResBins[resbin]; @@ -141,4 +148,4 @@ void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_ output_score = (l1ct::nn_assoc_t)nn_output_score[0]; } -#endif \ No newline at end of file +#endif From 0ef68dc783b26cfa07631e186c15000d45cf7a64 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Fri, 5 Jun 2026 17:17:13 +0200 Subject: [PATCH 08/92] Update path for including v0 NNvtx model for emulator in CC --- L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index e979bbafeb2f5..dee0a0a93f7e7 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -115,7 +115,7 @@ void NNVtxAssoc::NNVtxAssocDebug() { #else -#include "L1TNNVtx_Assoc_Model/L1TNNVtx_Assoc_Model_v0/NN/L1TNNVtx_Assoc_Model_v0.h" +#include "NNVtx/L1TNNVtx_Assoc_Model_v0/NN/L1TNNVtx_Assoc_Model_v0.h" void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_assoc_t& output_score) { int resbin = 0; From f087803b6a51b8bd8fcc5dfdc057c582580005fd Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Sat, 6 Jun 2026 07:13:15 +0200 Subject: [PATCH 09/92] Attempt to use sizeof for HLS compilation --- L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index dee0a0a93f7e7..0490c92dde859 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -119,7 +119,7 @@ void NNVtxAssoc::NNVtxAssocDebug() { void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_assoc_t& output_score) { int resbin = 0; - int Nresbins = std::size(associationNetworkEtaBounds); + int Nresbins = sizeof(associationNetworkEtaBounds) / sizeof(associationNetworkEtaBounds[0]); l1ct::eta_t temp_hwEta = t.hwEta; if (temp_hwEta < 0) temp_hwEta = -temp_hwEta; From c7013cefd4f0352667b2e4c0583126579e723379 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Sat, 6 Jun 2026 07:38:04 +0200 Subject: [PATCH 10/92] Use correct namespace for cms-hls4ml model version --- L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index 0490c92dde859..9fba9e15c8a7a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -137,14 +137,14 @@ void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_ nn_inputtype fDz_ = t.hwZ0 - v.hwZ0; nn_inputtype association_input[N_NN_ASSOC_FEATURES]; - L1TNNVtx_Assoc_Model_v0::result_t nn_output_score[N_NN_ASSOC_OUTPUTS]; + hls4ml_L1TNNVtx_Assoc_Model_v0::result_t nn_output_score[N_NN_ASSOC_OUTPUTS]; association_input[0] = fPt_; // Obj pT association_input[1] = fMVA_; // Obj track quality association_input[2] = fResBin_ / 16; // Obj z0 resolution bin (rescaled) association_input[3] = fDz_; // Obj delta z from the PV - L1TNNVtx_Assoc_Model_v0::NNvtx_assoc(association_input, nn_output_score); + hls4ml_L1TNNVtx_Assoc_Model_v0::L1TNNVtx_Assoc_Model_v0(association_input, nn_output_score); output_score = (l1ct::nn_assoc_t)nn_output_score[0]; } From 55373d72288baae2efa5634ffe8a705d475730f0 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Sat, 6 Jun 2026 08:21:23 +0200 Subject: [PATCH 11/92] Use emulator model's input type --- L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc index 9fba9e15c8a7a..d44d00d974ae8 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/NNVtxAssoc.cc @@ -136,7 +136,7 @@ void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_ nn_inputtype fMVA_ = t.hwQuality; nn_inputtype fDz_ = t.hwZ0 - v.hwZ0; - nn_inputtype association_input[N_NN_ASSOC_FEATURES]; + hls4ml_L1TNNVtx_Assoc_Model_v0::input_t association_input[N_NN_ASSOC_FEATURES]; hls4ml_L1TNNVtx_Assoc_Model_v0::result_t nn_output_score[N_NN_ASSOC_OUTPUTS]; association_input[0] = fPt_; // Obj pT From d906940ff08648536664c5d9496373772db665ea Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 13 Jun 2025 17:35:13 -0500 Subject: [PATCH 12/92] add option for TM18 tdr regionizer --- .../interface/regionizer/tdr_regionizer_ref.h | 2 ++ .../src/regionizer/tdr_regionizer_ref.cpp | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h index 3ee4950c81e01..737dc32d27b55 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h @@ -18,6 +18,8 @@ namespace l1ct { uint32_t nmu, uint32_t nclocks, std::vector bigRegionEdges, + uint32_t netaInBR, + uint32_t nphiInBR, bool dosort); // note: this one will work only in CMSSW diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp index 29a224ff1df5a..b95f824b98663 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp @@ -14,6 +14,8 @@ l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(const edm::ParameterSet& iCon iConfig.getParameter("nMu"), iConfig.getParameter("nClocks"), iConfig.getParameter>("bigRegionEdges"), + iConfig.getParameter("netaInBR"), + iConfig.getParameter("nphiInBR"), iConfig.getParameter("doSort")) { debug_ = iConfig.getUntrackedParameter("debug"); } @@ -26,7 +28,9 @@ edm::ParameterSetDescription l1ct::TDRRegionizerEmulator::getParameterSetDescrip description.add("nEmCalo", 12); description.add("nMu", 2); description.add("doSort", false); - description.add>("bigRegionEdges", {-560, -80, 400, -560}); + description.add>("bigRegionEdges", {-560, -560}); + description.add("netaInBR", 6); + description.add("nphiInBR", 9); description.addUntracked("debug", false); return description; } @@ -38,6 +42,8 @@ l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(uint32_t ntk, uint32_t nmu, uint32_t nclocks, std::vector bigRegionEdges, + uint32_t netaInBR, + uint32_t nphiInBR, bool dosort) : RegionizerEmulator(), ntk_(ntk), @@ -47,8 +53,8 @@ l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(uint32_t ntk, nclocks_(nclocks), bigRegionEdges_(bigRegionEdges), dosort_(dosort), - netaInBR_(6), - nphiInBR_(3), + netaInBR_(netaInBR), + nphiInBR_(nphiInBR), init_(false) { nBigRegions_ = bigRegionEdges_.size() - 1; } From 6c4f4a2333dcd155e192d6d7c678d0933b6853cd Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 31 Oct 2025 17:15:25 -0500 Subject: [PATCH 13/92] stapshot of work towards TM18 GCT --- .../interface/layer1_emulator.h | 6 ++--- .../L1TParticleFlow/src/layer1_emulator.cpp | 27 ++++--------------- .../plugins/L1TCorrelatorLayer1Producer.cc | 3 +-- .../src/regionizer/tdr_regionizer_ref.cpp | 5 ++-- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h index a3967e318122b..09f69542f0928 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -273,9 +273,7 @@ namespace l1ct { std::vector>> track; DetectorSector> muon; // muons are global std::vector>> hgcalcluster; - std::vector>> gctHad; // the 48 hadronic clusters from the GCT - std::vector>> gctEm; // the 36 EM clusters from the GCT - // (The trigger towers that follow the clusters are not included in the above data) + std::vector>> gctcluster; // constains both em and pf clusters bool read(std::fstream &from); bool write(std::fstream &to) const; @@ -356,7 +354,7 @@ namespace l1ct { }; struct Event { - enum { VERSION = 14 }; + enum { VERSION = 15 }; uint32_t run, lumi; uint64_t event; RawInputs raw; diff --git a/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp index 76ee4ececcb34..cfa734fe639f0 100644 --- a/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp +++ b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp @@ -169,16 +169,8 @@ bool l1ct::RawInputs::read(std::fstream& from) { if (!readVar(from, number)) return false; - gctHad.resize(number); - for (auto& v : gctHad) { - if (!(v.region.read(from) && readMany(from, v.obj))) - return false; - } - - if (!readVar(from, number)) - return false; - gctEm.resize(number); - for (auto& v : gctEm) { + gctcluster.resize(number); + for (auto& v : gctcluster) { if (!(v.region.read(from) && readMany(from, v.obj))) return false; } @@ -208,21 +200,14 @@ bool l1ct::RawInputs::write(std::fstream& to) const { return false; } - number = gctHad.size(); + number = gctcluster.size(); if (!writeVar(number, to)) return false; - for (const auto& v : gctHad) { + for (const auto& v : gctcluster) { if (!(v.region.write(to) && writeMany(v.obj, to))) return false; } - number = gctEm.size(); - if (!writeVar(number, to)) - return false; - for (const auto& v : gctEm) { - if (!(v.region.write(to) && writeMany(v.obj, to))) - return false; - } return true; } void l1ct::RawInputs::clear() { @@ -231,9 +216,7 @@ void l1ct::RawInputs::clear() { muon.clear(); for (auto& h : hgcalcluster) h.clear(); - for (auto& h : gctHad) - h.clear(); - for (auto& h : gctEm) + for (auto& h : gctcluster) h.clear(); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index b54b611885a10..47f3890752248 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -95,8 +95,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { std::unique_ptr trackInput_; std::unique_ptr muonInput_; std::unique_ptr hgcalInput_; - std::unique_ptr gctHadInput_; - std::unique_ptr gctEmInput_; + std::unique_ptr gctInput_; // This will chaged std::unique_ptr regionizer_; std::unique_ptr l1pfalgo_; std::unique_ptr l1pualgo_; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp index b95f824b98663..ca8d91f3461e5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp @@ -65,6 +65,7 @@ void l1ct::TDRRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedI const std::vector& out) { if (debug_) { dbgCout() << "doing init, out_size = " << out.size() << std::endl; + dbgCout() << "nBigRegions_ = " << nBigRegions_ << std::endl; } assert(!init_); init_ = true; @@ -73,9 +74,9 @@ void l1ct::TDRRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedI tkRegionizers_.emplace_back( netaInBR_, nphiInBR_, ntk_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); hadCaloRegionizers_.emplace_back( - netaInBR_, nphiInBR_, ncalo_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_ / 3, 1, false); // TM6 + netaInBR_, nphiInBR_, ncalo_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); // TM6 emCaloRegionizers_.emplace_back( - netaInBR_, nphiInBR_, nem_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_ / 3, 1, false); // TM6 + netaInBR_, nphiInBR_, nem_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); // TM6 muRegionizers_.emplace_back( netaInBR_, nphiInBR_, nmu_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); } From 9c4d764ecfc69249f1d1fd8e19c244ce7974b400 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 6 Jan 2026 11:27:53 -0600 Subject: [PATCH 14/92] copy changes in Phase2L1ParticleFlow from 151x_bar_cl1_tm18_gct --- .../L1TCorrelatorLayer1PatternFileWriter.h | 14 ++---- .../plugins/L1TCorrelatorLayer1Producer.cc | 35 ++++++------- .../python/l1ctLayer1_patternWriters_cff.py | 6 +-- .../L1TCorrelatorLayer1PatternFileWriter.cc | 50 ++++++------------- .../test/make_l1ct_binaryFiles_cfg.py | 26 ++++++---- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h index cffcd935a165e..0302cd3e5b067 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -31,18 +31,16 @@ class L1TCorrelatorLayer1PatternFileWriter { // They are not configurable in the current architecture. const unsigned int tfTmuxFactor_ = 18, tfLinksFactor_ = 1; const unsigned int hgcTmuxFactor_ = 18, hgcLinksFactor_ = 4; - const unsigned int gctEmTmuxFactor_ = 6, gctEmLinksFactor_ = 1; - const unsigned int gctHadTmuxFactor_ = 6, gctHadLinksFactor_ = 1; + const unsigned int gctTmuxFactor_ = 18, gctEmLinksFactor_ = 1; const unsigned int gmtTmuxFactor_ = 18, gmtLinksFactor_ = 1; const unsigned int gttTmuxFactor_ = 6, gttLinksFactor_ = 1; - const unsigned int tfTimeslices_, hgcTimeslices_, gctEmTimeslices_, gctHadTimeslices_, gmtTimeslices_, gttTimeslices_; + const unsigned int tfTimeslices_, hgcTimeslices_, gctTimeslices_, gmtTimeslices_, gttTimeslices_; uint32_t gctLinksEcal_, gctLinksHad_; bool gctSingleLink_; uint32_t gmtNumberOfMuons_; uint32_t gttNumberOfPVs_; uint32_t tfNumberOfTracks_; // if this messes up Serenity, change to int32 and only apply if not negative? - uint32_t gctNumberOfEMs_; - uint32_t gctNumberOfHads_; + uint32_t gctNumberOfObjects_; uint32_t gttLatency_; std::vector outputRegions_, outputLinksPuppi_; @@ -72,8 +70,7 @@ class L1TCorrelatorLayer1PatternFileWriter { static Partition parsePartition(const std::string& partition); static std::unique_ptr describeTF(); - static std::unique_ptr describeGCTEm(); - static std::unique_ptr describeGCTHad(); + static std::unique_ptr describeGCT(); static std::unique_ptr describeHGC(); static std::unique_ptr describeGMT(); static std::unique_ptr describeGTT(); @@ -98,8 +95,7 @@ class L1TCorrelatorLayer1PatternFileWriter { static std::unique_ptr describeLinks(const std::string& prefix); void writeTF(const l1ct::Event& event, l1t::demo::EventData& out); - void writeGCTEm(const l1ct::Event& event, l1t::demo::EventData& out); - void writeGCTHad(const l1ct::Event& event, l1t::demo::EventData& out); + void writeGCT(const l1ct::Event& event, l1t::demo::EventData& out); void writeHGC(const l1ct::Event& event, l1t::demo::EventData& out); void writeGMT(const l1ct::Event& event, l1t::demo::EventData& out); void writeGTT(const l1ct::Event& event, l1t::demo::EventData& out); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 47f3890752248..631218d3e8007 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -48,10 +48,9 @@ #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" -// #include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" constexpr unsigned int calomapping[] = {3, 0, 9, 6, 4, 1, 10, 7, 5, 2, 11, 8}; @@ -86,8 +85,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { edm::EDGetTokenT hadHGCalCands_; // can alternately give the raw containers (for GCT) - edm::EDGetTokenT emGCTRawCands_; - edm::EDGetTokenT hadGCTRawCands_; + edm::EDGetTokenT gctRawCands_; float emPtCut_, hadPtCut_; @@ -95,7 +93,8 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { std::unique_ptr trackInput_; std::unique_ptr muonInput_; std::unique_ptr hgcalInput_; - std::unique_ptr gctInput_; // This will chaged + std::unique_ptr gctHadInput_; + std::unique_ptr gctEmInput_; std::unique_ptr regionizer_; std::unique_ptr l1pfalgo_; std::unique_ptr l1pualgo_; @@ -278,25 +277,23 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet throw cms::Exception("Configuration", "Unsupported hgcalInputConversionAlgo"); } const std::string &gctEmInAlgo = iConfig.getParameter("gctEmInputConversionAlgo"); - const edm::InputTag emClusters = iConfig.getParameter("emClusters"); - if (!emClusters.label().empty()) { + const edm::InputTag gctClusters = iConfig.getParameter("gctClusters"); + if (!gctClusters.label().empty()) { if (gctEmInAlgo == "Emulator") { gctEmInput_ = std::make_unique( iConfig.getParameter("gctEmInputConversionParameters")); - emGCTRawCands_ = consumes(emClusters); + gctRawCands_ = consumes(gctClusters); // also for hadronic } else if (gctEmInAlgo != "None") throw cms::Exception("Configuration", "Unsupported gctEmInputConversionAlgo"); } const std::string &gctHadInAlgo = iConfig.getParameter("gctHadInputConversionAlgo"); - if (!hadClusters.label().empty()) { - if (gctHadInAlgo == "Emulator") { - gctHadInput_ = std::make_unique( - iConfig.getParameter("gctHadInputConversionParameters")); - hadGCTRawCands_ = consumes(hadClusters); - } else if (gctHadInAlgo == "Ideal") { + if (!gctClusters.label().empty() && gctHadInAlgo == "Emulator") { + gctHadInput_ = std::make_unique( + iConfig.getParameter("gctHadInputConversionParameters")); + } else if (!hadClusters.label().empty() && gctHadInAlgo == "Ideal") { hadGCTCands_ = consumes(hadClusters); - } else if (gctHadInAlgo != "None") - throw cms::Exception("Configuration", "Unsupported gctHadInputConversionAlgo"); + } else if (gctHadInAlgo != "None") + throw cms::Exception("Configuration", "Unsupported gctHadInputConversionAlgo"); } const std::string ®algo = iConfig.getParameter("regionizerAlgo"); @@ -394,7 +391,7 @@ void L1TCorrelatorLayer1Producer::fillDescriptions(edm::ConfigurationDescription // Inputs and cuts desc.add("tracks", edm::InputTag("")); desc.add("muons", edm::InputTag("l1tSAMuonsGmt", "prompt")); - desc.add("emClusters", edm::InputTag("")); + desc.add("gctClusters", edm::InputTag("")); desc.add("hadClusters", edm::InputTag("")); desc.add("vtxCollection", edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation")); desc.add("vtxCollectionEmulation", true); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 8bec8adc9dde1..bc3ba02ebc965 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -8,7 +8,7 @@ ## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now _barrelWriterOutputOnly = cms.PSet( partition = cms.string("Barrel"), - tmuxFactor = cms.uint32(6), + tmuxFactor = cms.uint32(18), outputLinksPuppi = cms.vuint32(*range(6)), outputLinkEgamma = cms.int32(6), nEgammaObjectsOut = cms.uint32(16), @@ -29,12 +29,12 @@ gctEmSectors = cms.VPSet(), gctHadSectors = cms.VPSet(), tfNumberOfTracks = cms.uint32(108), - gctNumberOfEMs = cms.uint32(32), - gctNumberOfHads = cms.uint32(48), + gctNumberOfObjects = cms.uint32(162), ) ## Barrel (54) split in 3 phi slices (EMP format) barrelWriterOutputOnlyPhiConfigs = [ _barrelWriterOutputOnly.clone( + tmuxFactor = cms.uint32(6), outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(6) for i in range(3) ]), outputBoard = cms.int32(ip), outputFileName = cms.string("l1BarrelPhi%d-outputs" % (ip+1)) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 85942c7d8af00..59865ccd2646e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -14,8 +14,7 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const writeDebugs_(!iConfig.getParameter("debugFileName").empty()), tfTimeslices_(std::max(1u, tfTmuxFactor_ / tmuxFactor_)), hgcTimeslices_(std::max(1u, hgcTmuxFactor_ / tmuxFactor_)), - gctEmTimeslices_(std::max(1u, gctEmTmuxFactor_ / tmuxFactor_)), - gctHadTimeslices_(std::max(1u, gctHadTmuxFactor_ / tmuxFactor_)), + gctTimeslices_(std::max(1u, gctTmuxFactor_ / tmuxFactor_)), gmtTimeslices_(std::max(1u, gmtTmuxFactor_ / tmuxFactor_)), gttTimeslices_(std::max(1u, gttTmuxFactor_ / tmuxFactor_)), outputBoard_(-1), @@ -41,14 +40,10 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const tfTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - (tfNumberOfTracks_ * 3 / 2)}; } if (partition_ == Partition::Barrel) { - configTimeSlices(iConfig, "gctEm", eventTemplate.raw.gctEm.size(), gctEmTimeslices_, gctEmLinksFactor_); - gctNumberOfEMs_ = iConfig.getParameter("gctNumberOfEMs"); - channelSpecsInput_["gctEm"] = {tmuxFactor_ * gctEmTimeslices_, - gctEmTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gctNumberOfEMs_}; - configTimeSlices(iConfig, "gctHad", eventTemplate.raw.gctHad.size(), gctHadTimeslices_, gctHadLinksFactor_); - gctNumberOfHads_ = iConfig.getParameter("gctNumberOfHads"); - channelSpecsInput_["gctHad"] = {tmuxFactor_ * gctHadTimeslices_, - gctHadTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gctNumberOfHads_}; + configTimeSlices(iConfig, "gct", eventTemplate.raw.gctcluster.size(), gctTimeslices_, gctEmLinksFactor_); + gctNumberOfObjects_ = iConfig.getParameter("gctNumberOfObjects"); + channelSpecsInput_["gct"] = {tmuxFactor_ * gctTimeslices_, + gctTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gctNumberOfObjects_}; } if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { configTimeSlices(iConfig, "hgc", eventTemplate.raw.hgcalcluster.size(), hgcTimeslices_, hgcLinksFactor_); @@ -199,7 +194,7 @@ edm::ParameterSetDescription L1TCorrelatorLayer1PatternFileWriter::getParameterS description.add("nPFOutMuon", 0); description.ifValue(edm::ParameterDescription("partition", "Barrel", true), - "Barrel" >> (describeTF() and describeGCTEm() and describeGCTHad() and describeGTT() and + "Barrel" >> (describeTF() and describeGCT() and describeGTT() and describeGMT() and describePuppi() and describeEG()) or "HGCal" >> (describeTF() and describeHGC() and describeGTT() and describeGMT() and describePuppi() and describeEG()) or @@ -212,11 +207,8 @@ std::unique_ptr L1TCorrelatorLayer1PatternFileWri return describeTimeSlices("tf") and edm::ParameterDescription( "tfNumberOfTracks", 108, true); // need to change if Serenity needs variable } -std::unique_ptr L1TCorrelatorLayer1PatternFileWriter::describeGCTEm() { - return describeTimeSlices("gctEm") and edm::ParameterDescription("gctNumberOfEMs", 32, true); -} -std::unique_ptr L1TCorrelatorLayer1PatternFileWriter::describeGCTHad() { - return describeTimeSlices("gctHad") and edm::ParameterDescription("gctNumberOfHads", 48, true); +std::unique_ptr L1TCorrelatorLayer1PatternFileWriter::describeGCT() { + return describeTimeSlices("gct") and edm::ParameterDescription("gctNumberOfObjects", 162, true); } std::unique_ptr L1TCorrelatorLayer1PatternFileWriter::describeHGC() { return describeTimeSlices("hgc"); @@ -246,8 +238,7 @@ void L1TCorrelatorLayer1PatternFileWriter::write(const l1ct::Event& event) { writeTF(event, inputs); } if (partition_ == Partition::Barrel) { - writeGCTEm(event, inputs); - writeGCTHad(event, inputs); + writeGCT(event, inputs); } if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { writeHGC(event, inputs); @@ -403,25 +394,14 @@ void L1TCorrelatorLayer1PatternFileWriter::writeTF(const l1ct::Event& event, l1t } } -void L1TCorrelatorLayer1PatternFileWriter::writeGCTEm(const l1ct::Event& event, l1t::demo::EventData& out) { - for (unsigned int iS = 0, nS = event.raw.gctEm.size(); iS < nS; ++iS) { - l1t::demo::LinkId key{"gctEm", iS}; - if (channelIdsInput_.count(key) == 0) - continue; - std::vector> gctEm = event.raw.gctEm[iS].obj; - gctEm.resize(gctNumberOfEMs_, ap_uint<64>(0)); - out.add(key, gctEm); - } -} - -void L1TCorrelatorLayer1PatternFileWriter::writeGCTHad(const l1ct::Event& event, l1t::demo::EventData& out) { - for (unsigned int iS = 0, nS = event.raw.gctHad.size(); iS < nS; ++iS) { - l1t::demo::LinkId key{"gctHad", iS}; +void L1TCorrelatorLayer1PatternFileWriter::writeGCT(const l1ct::Event& event, l1t::demo::EventData& out) { + for (unsigned int iS = 0, nS = event.raw.gctcluster.size(); iS < nS; ++iS) { + l1t::demo::LinkId key{"gct", iS}; if (channelIdsInput_.count(key) == 0) continue; - std::vector> gctHad = event.raw.gctHad[iS].obj; - gctHad.resize(gctNumberOfHads_, ap_uint<64>(0)); - out.add(key, gctHad); + std::vector> gctclusters = event.raw.gctcluster[iS].obj; + gctclusters.resize(gctNumberOfObjects_, ap_uint<64>(0)); + out.add(key, gctclusters); } } diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index d4456abf87bb7..6ea272cccdfa4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -68,18 +68,19 @@ process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') from L1Trigger.Configuration.SimL1Emulator_cff import l1tSAMuonsGmt process.l1tSAMuonsGmt = l1tSAMuonsGmt.clone() -from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import l1tPhase2L1CaloEGammaEmulator -process.l1tPhase2L1CaloEGammaEmulator = l1tPhase2L1CaloEGammaEmulator.clone() -from L1Trigger.L1CaloTrigger.l1tPhase2CaloPFClusterEmulator_cfi import l1tPhase2CaloPFClusterEmulator -process.l1tPhase2CaloPFClusterEmulator = l1tPhase2CaloPFClusterEmulator.clone() -from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator -process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() +# from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import l1tPhase2L1CaloEGammaEmulator +# process.l1tPhase2L1CaloEGammaEmulator = l1tPhase2L1CaloEGammaEmulator.clone() +# from L1Trigger.L1CaloTrigger.l1tPhase2CaloPFClusterEmulator_cfi import l1tPhase2CaloPFClusterEmulator +# process.l1tPhase2CaloPFClusterEmulator = l1tPhase2CaloPFClusterEmulator.clone() +# from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator +# process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() + +from L1Trigger.L1CaloTrigger.l1tPhase2CaloToCorrelatorTMI18_cfi import l1tPhase2CaloToCorrelatorTMI18 +process.l1tPhase2CaloToCorrelatorTMI18 = l1tPhase2CaloToCorrelatorTMI18.clone() process.L1TInputTask = cms.Task( process.l1tSAMuonsGmt, - process.l1tPhase2L1CaloEGammaEmulator, - process.l1tPhase2CaloPFClusterEmulator, - process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator + process.l1tPhase2CaloToCorrelatorTMI18 ) @@ -117,8 +118,10 @@ nMu = cms.uint32(2), nClocks = cms.uint32(162), doSort = cms.bool(False), - bigRegionEdges = cms.vint32(-560, -80, 400, -560), - debug = cms.untracked.bool(False) + bigRegionEdges = cms.vint32(-560, -560), + netaInBR = cms.uint32(6), + nphiInBR = cms.uint32(9), + debug = cms.untracked.bool(True) ) process.l1tLayer1BarrelTDR.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelTDR.pfAlgoParameters.nSelCalo = 15 @@ -301,3 +304,4 @@ ) process.source.fileNames = [ '/store/cmst3/group/l1tr/FastPUPPI/14_2_X/fpinputs_140X/v0/TT_PU200/inputs140X_1.root' ] +process.source.fileNames = ["file:inputs140X_1.root "] From 027fede0d9242fb5005e32d9f75be327eda1f129 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 6 Jan 2026 17:58:05 -0600 Subject: [PATCH 15/92] make it compile --- .../plugins/L1TCorrelatorLayer1Producer.cc | 89 ++++++++++--------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 631218d3e8007..76e62c7a39dda 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -48,9 +48,11 @@ #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" +// FIXME! These are the old TM6 ones +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" + #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" constexpr unsigned int calomapping[] = {3, 0, 9, 6, 4, 1, 10, 7, 5, 2, 11, 8}; @@ -85,7 +87,8 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { edm::EDGetTokenT hadHGCalCands_; // can alternately give the raw containers (for GCT) - edm::EDGetTokenT gctRawCands_; + // FIXME! These should be all the candidates, not just Em + edm::EDGetTokenT gctRawCands_; float emPtCut_, hadPtCut_; @@ -150,9 +153,9 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { void addHGCalHadCalo(const l1t::HGCalMulticluster &calo, const edm::Ptr &caloPtr); // GCT input clusters void addGCTHadCalo(const l1t::PFCluster &calo, const edm::Ptr &caloPtr); - // for GCT raw calos as input - void addGCTEmCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); - void addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); + // for GCT raw calos as input (FIXME) + void addGCTCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); + //void addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); // add objects in already-decoded format void addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t); void addDecodedMuon(l1ct::DetectorSector &sec, const l1t::SAMuon &t); @@ -280,11 +283,12 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet const edm::InputTag gctClusters = iConfig.getParameter("gctClusters"); if (!gctClusters.label().empty()) { if (gctEmInAlgo == "Emulator") { - gctEmInput_ = std::make_unique( - iConfig.getParameter("gctEmInputConversionParameters")); - gctRawCands_ = consumes(gctClusters); // also for hadronic - } else if (gctEmInAlgo != "None") + gctEmInput_ = std::make_unique( // FIXME + iConfig.getParameter("gctInputConversionParameters")); + gctRawCands_ = consumes(gctClusters); // FIXME + } else if (gctEmInAlgo != "None") { throw cms::Exception("Configuration", "Unsupported gctEmInputConversionAlgo"); + } } const std::string &gctHadInAlgo = iConfig.getParameter("gctHadInputConversionAlgo"); if (!gctClusters.label().empty() && gctHadInAlgo == "Emulator") { @@ -292,7 +296,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet iConfig.getParameter("gctHadInputConversionParameters")); } else if (!hadClusters.label().empty() && gctHadInAlgo == "Ideal") { hadGCTCands_ = consumes(hadClusters); - } else if (gctHadInAlgo != "None") + } else if (gctHadInAlgo != "None") { throw cms::Exception("Configuration", "Unsupported gctHadInputConversionAlgo"); } @@ -529,13 +533,13 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe // ------ READ CALOS ----- // this is for parsing raw calo information - if (!emGCTRawCands_.isUninitialized()) { - auto caloHandle = iEvent.getHandle(emGCTRawCands_); + if (!gctRawCands_.isUninitialized()) { + auto caloHandle = iEvent.getHandle(gctRawCands_); const auto &links = *caloHandle; for (unsigned int ic = 0; ic < links.size(); ++ic) { const auto &link = links[ic]; for (unsigned int ie = 0; ie < link.size(); ++ie) { - addGCTEmCaloRaw(link, ic, ie); + addGCTCaloRaw(link, ic, ie); // FIXME? } } } @@ -551,16 +555,17 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe } } - if (!hadGCTRawCands_.isUninitialized()) { - auto caloHandle = iEvent.getHandle(hadGCTRawCands_); - const auto &links = *caloHandle; - for (unsigned int ic = 0; ic < links.size(); ++ic) { - const auto &link = links[ic]; - for (unsigned int ie = 0; ie < link.size(); ++ie) { - addGCTHadCaloRaw(link, ic, ie); - } - } - } + // FIXME + // if (!hadGCTRawCands_.isUninitialized()) { + // auto caloHandle = iEvent.getHandle(hadGCTRawCands_); + // const auto &links = *caloHandle; + // for (unsigned int ic = 0; ic < links.size(); ++ic) { + // const auto &link = links[ic]; + // for (unsigned int ie = 0; ie < link.size(); ++ie) { + // addGCTHadCaloRaw(link, ic, ie); + // } + // } + // } if (!hadGCTCands_.isUninitialized()) { auto caloHandle = iEvent.getHandle(hadGCTCands_); @@ -862,8 +867,7 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet event_.decoded.emcalo.clear(); event_.decoded.hadcalo.clear(); event_.raw.hgcalcluster.clear(); - event_.raw.gctEm.clear(); - event_.raw.gctHad.clear(); + event_.raw.gctcluster.clear(); for (const edm::ParameterSet &preg : iConfig.getParameter("caloSectors")) { std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); @@ -883,8 +887,7 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); - event_.raw.gctEm.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); - event_.raw.gctHad.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); + event_.raw.gctcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); } } } @@ -997,27 +1000,27 @@ void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster & } } -void L1TCorrelatorLayer1Producer::addGCTEmCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, +void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, unsigned int linkidx, unsigned int entidx) { // in the "Ideal" regionizer, ignore the second set that is sent; only use the first auto caloIdx = calomapping[linkidx]; - if (caloIdx < event_.raw.gctEm.size()) { - event_.raw.gctEm[caloIdx].obj.push_back(link[entidx].data()); - addDecodedGCTEmCalo(event_.decoded.emcalo[caloIdx], link[entidx]); + if (caloIdx < event_.raw.gctcluster.size()) { + event_.raw.gctcluster[caloIdx].obj.push_back(link[entidx].data()); + addDecodedGCTEmCalo(event_.decoded.emcalo[caloIdx], link[entidx]); // FIXME } } -void L1TCorrelatorLayer1Producer::addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, - unsigned int linkidx, - unsigned int entidx) { - // in the "Ideal" regionizer, ignore the second set that is sent; only use the first - auto caloIdx = calomapping[linkidx]; - if (caloIdx < event_.raw.gctHad.size()) { - event_.raw.gctHad[caloIdx].obj.push_back(link[entidx].data()); - addDecodedGCTHadCalo(event_.decoded.hadcalo[caloIdx], link[entidx]); - } -} +// void L1TCorrelatorLayer1Producer::addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, +// unsigned int linkidx, +// unsigned int entidx) { +// // in the "Ideal" regionizer, ignore the second set that is sent; only use the first +// auto caloIdx = calomapping[linkidx]; +// if (caloIdx < event_.raw.gctHad.size()) { +// event_.raw.gctHad[caloIdx].obj.push_back(link[entidx].data()); +// addDecodedGCTHadCalo(event_.decoded.hadcalo[caloIdx], link[entidx]); +// } +// } void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t) { std::pair tkAndSel; From a83e599ddb1b3ee396087a0bb56162f12d9386d7 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Sat, 10 Jan 2026 21:48:32 -0600 Subject: [PATCH 16/92] first version with tdr_alt regionizer --- .../tdr_alt_regionizer_elements_ref.h | 175 +++++++ .../tdr_alt_regionizer_elements_ref.icc | 433 ++++++++++++++++++ .../regionizer/tdr_alt_regionizer_ref.h | 48 ++ .../src/regionizer/tdr_alt_regionizer_ref.cpp | 122 +++++ 4 files changed, 778 insertions(+) create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h new file mode 100644 index 0000000000000..259b7829707fd --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -0,0 +1,175 @@ +#ifndef tdr_alt_regionizer_elements_ref_h +#define tdr_alt_regionizer_elements_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +#include +#include +#include +#include +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +namespace l1ct { + namespace tdr_alt_regionizer { + + inline int phi_wrap(int local_phi) { + if (local_phi > l1ct::Scales::INTPHI_PI) + local_phi -= l1ct::Scales::INTPHI_TWOPI; + else if (local_phi <= -l1ct::Scales::INTPHI_PI) + local_phi += l1ct::Scales::INTPHI_TWOPI; + return local_phi; + } + + + /// the components that make up the L1 regionizer buffer + template + class BufferEntry { + public: + BufferEntry() {} + BufferEntry(const T& obj, int glbeta, int glbphi); + + int pt() const { return obj_.intPt(); } + int glbPhi() const { return glbphi_; } + int glbEta() const { return glbeta_; } + + //T obj() { return obj_; } + const T& obj() const { return obj_; } + const T + + private: + T obj_; + /// the SR linearized indices (can index regionmap_) where this object needs to go + int glbeta_, glbphi_; + }; + + /// The L1 regionizer buffer (corresponding to level1_fifo_buffer.vhd) + template + class Buffer { + public: + Buffer() : {} + + void addEntry(const T& obj, + std::vector srs, + int glbeta, + int glbphi); + + bool empty(size_t sr) const; + BufferEntry getEntry(size_t sr); + + + + // mainly for debug/validation, to check that nothing is left over after an event + // This is the number of entries in all the deques, not necessarily the number of + // entries in the map. + unsigned int numEntries() const; + + void reset() { data_.clear(); } + + private: + + /// The actual data, indexed by the physical SR + std::map>> data_; + + }; + + template + class Regionizer { + public: + Regionizer() = delete; + Regionizer(unsigned int maxobjects, + bool debug = false); + + void initSectors(const std::vector>& sectors); + void initSectors(const DetectorSector& sector); + void initRegions(const std::vector& regions); + + void fillBuffers(const std::vector>& sectors); + void fillBuffers(const DetectorSector& sector); + + void run(); + + void reset(); + + const std::vector>& smallRegions() const return {smallRegionObjects_; } + void clearSmallRegions(); + + void printDebug(int count) const; + + private: + + const size_t SMALL_REGION_ETA_COUNT = 6; + const size_t SMALL_REGION_PHI_COUNT = 9; + + /// @brief convert to logical SR + /// @param sr linear small region + /// @return pair (eta, phi) region index) + std::pair get_small_region(size_t sr) const; + + /// logical links associated with a logical sr (customized for each type) + std::vector linksForSR(size_t sr) const; + + unsigned int numBuffers() const { return buffers_.size(); } + unsigned int numEntries(unsigned int bufferIndex) const { return buffers_[bufferIndex].numEntries(); } + + std::vector getSmallRegions(int glbeta, int glbphi) const; + + /// fill the buffers with an event's link data. The buffers should be empty--checked by assert + void setBuffers(const std::vector>&& objvecvec); + + /// 'put' object in small region. The sr is physics + void addToSmallRegion(size_t sr, BufferEntry&& bufEntry); + + /// returns 2D arrays, sectors (links) first dimension, objects second + std::vector> fillLinks(const std::vector>& sectors) const; + std::vector> fillLinks(const DetectorSector& sector) const; + + // this function is for sorting small regions first in phi and then in eta. + // It takes regions_ indices + bool sortRegionsRegular(size_t a, size_t b) const; + + bool sortSectors(size_t a, size_t b) const; + + bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; + + /// get the index in regions_ for a particular SR. + size_t regionIndex(int sr) const { return regionmap_.at(sr); } + + /// get the logical buffer index (i.e. the index in the order in the firmware) + size_t logicBuffIndex(size_t bufIdx) const; + + + /// The numbers of eta and phi in a big region (board) + unsigned int neta_, nphi_; + /// The maximum number of objects to output per small region + unsigned int maxobjects_; + + /// the region information associated with each input sector (link). Note, this is indexed in physical order + std::vector sectors_; + + /// the region information associated with each SR + std::vector regions_; + + /// indices of regions that are in the big region (board) + std::vector regionmap_; + + /// indices maps the sectors from the way they appear in the software to the (logical) order they are done in the regionizer firmware + std::vector sectorMapPhysToLog_; + + /// the inverse mapping of sectormap_ (only used for debug printing) + std::vector sectorMapLogToPhys_; + + /// The buffers. There is one buffer per link (or sector). Note, this is also indexed in physical order (= same index as sectors) + std::vector> buffers_; + + /// The objects in each small region handled in board; Indexing corresponds to that in regionmap_ + std::vector> smallRegionObjects_; + + bool debug_; + }; + + } // namespace tdr_regionizer +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc new file mode 100644 index 0000000000000..daaead0cdd6e7 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -0,0 +1,433 @@ +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// BUFFER ENTRY AND BUFFER +template +l1ct::tdr_alt_regionizer::BufferEntry::BufferEntry( + const T& obj, int glbeta, int glbphi) + : obj_(obj), glbeta_(glbeta), glbphi_(glbphi) {} + +template +inline void l1ct::tdr_alt_regionizer::Buffer::addEntry(const T& obj, std::vector srIndices, + int glbeta, int glbphi) { + for (auto sr : srIndices) { + data_[sr].emplace_back(obj, glbeta, glbphi); // note, this creates a deque if needed + } +} + +unsigned int l1ct::tdr_alt_regionizer::Buffer::numEntries() const { + unsinged int count = 0; + for (const auto& [key, value] : data_) { + count += value.size(); + } + return count; +} + +// REGIONIZER +template +l1ct::tdr_alt_regionizer::Regionizer::Regionizer(unsigned int maxobjects, + bool debug) + : maxobjects_(maxobjects), debug_(debug) {} + +template +void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const std::vector>& sectors) { + + // we need a mapping of physical (what's in the sectors variable) to logical, + // but it's easier to create the inverse, first + + if (debug_) { + dbgCout() << "sectors.size() = " << sectors.size() << std::endl; + } + + for (const auto& sector : sectors) { + if (debug_) { + dbgCout() << "intEtaCenter() = " << sector.region.intEtaCenter() + << ", intPhiCenter() = " << sector.region.intPhiCenter() << std::endl; + } + sectorMapLogToPhys_.push_back(sectors_.size()); // currently set to 0, 1, 2, ... + sectors_.push_back(sector.region); + } + + buffers_.resize(sectors_size()); + + std::sort(sectorMapLogToPhys_.begin(), sectorMapLogToPhys_.end(), [this](size_t a, size_t b) { + return this->sortSectors(a, b); + }); + // now logical to physical mapping should be correct + + if (debug_) { + for (auto val : sectorMapLogToPhys_) { + dbgCout() << "sectorMapLogToPhys phys index = " << val << ", eta = " << sectors_[val].intEtaCenter() + << ", phi = " << sectors_[val].intPhiCenter() << std::endl; + } + } + + // now invert the sectorMapLogToPhys_ + sectorMapPhysToLog_.resize(sectorMapLogToPhys_.size()); + for (size_t i = 0; i < sectorMapLogToPhys_.size(); ++i) { + sectorMapPhysToLog_[sectorMapLogToPhys_[i]] = i; + } +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const DetectorSector& sector) { + sectors_.push_back(sector.region); + sectorMapLogToPhys_.push_back(0); + sectorMapPhysToLog_.push_back(0); + buffers_.resize(1); + if (debug_) { + dbgCout() << "Number of sectors: " << nsectors_ << std::endl; + } +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::fillBuffers(const std::vector>& sectors) { + setBuffers(fillLinks(sectors)); +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::fillBuffers(const DetectorSector& sector) { + setBuffers(fillLinks(sector)); +} + +// this function is for sorting small regions +// in eta first, then in phi +template +bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsRegular(size_t a, size_t b) const { + // first do eta + auto etaa = regions_[a].intEtaCenter(); + auto etab = regions_[b].intEtaCenter(); + auto phia = regions_[a].intPhiCenter(); + auto phib = regions_[b].intPhiCenter(); + return sortRegionsHelper(etaa, etab, phia, phib); +} + +// this function is for sorting small regions +// in eta first, then in phi +template +bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsHelper(int etaa, int etab, int phia, int phib) const { + // first do eta + if (etaa < etab) { + return true; + } else if (etaa > etab) { + return false; + } + + // if here, then etaa == etab, move to phi + if (bigRegionMax_ < bigRegionMin_) { + // the wraparound case, rewrap around pi + if (phia < 0) { + phia += l1ct::Scales::INTPHI_TWOPI; + } + if (phib < 0) { + phib += l1ct::Scales::INTPHI_TWOPI; + } + } + // regular phi + if (phia < phib) { + return true; + } else { + return false; + } +} + +// this function is for sorting the sectors +// in eta first, then in phi +template +bool l1ct::tdr_alt_regionizer::Regionizer::sortSectors(size_t a, size_t b) const { + // first do eta + auto etaa = sectors_[a].intEtaCenter(); + auto etab = sectors_[b].intEtaCenter(); + auto phia = sectors_[a].intPhiCenter(); + auto phib = sectors_[b].intPhiCenter(); + return sortRegionsHelper(etaa, etab, phia, phib); +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::initRegions(const std::vector& regions) { + regions_.resize(regions.size()); + smallRegionObjects_.resize(regions.size()); + for (unsigned int i = 0; i < regions.size(); ++i) { + regions_[i] = regions[i].region; + regionmap_.push_back(i); + if (debug_) { + dbgCout() << "region [" << i << "] eta/phi: " << regions_[i].intEtaCenter() << " " << regions_[i].intPhiCenter() + << ", eta half width = " << regions_[i].hwEtaHalfWidth.to_int() + << ", phi half width = " << regions_[i].hwPhiHalfWidth.to_int() + << ", eta extra = " << regions_[i].hwEtaExtra.to_int() + << ", phi extra = " << regions_[i].hwPhiExtra.to_int() << std::endl; + } + } + std::sort( + regionmap_.begin(), regionmap_.end(), [this](size_t a, size_t b) { return this->sortRegionsRegular(a, b); }); +} + + +template +std::vector l1ct::tdr_alt_regionizer::Regionizer::getSmallRegions(int glbeta, int glbphi) const { + std::vector srIndices; // the signal regions this object should go into + + // only iterate over regions covered by board + for (size_t i = 0; i < regionmap_.size(); i++) { + auto regionidx = regionIndex(i); + int regphi = phi_wrap(glbphi - regions_[regionidx].intPhiCenter()); + int regeta = glbeta - regions_[regionidx].intEtaCenter(); + + // add a special check to not have 3 eta regions + if (regions_[regionidx].isInside(regeta, regphi) && + !((glbeta == 57 && regeta == -115) || (glbeta == -57 && regeta == 115))) { + srIndices.push_back(i); + } + } + + return srIndices; +} + + +template +void l1ct::tdr_alt_regionizer::Regionizer::setBuffers(const std::vector>&& objvecvec) { + assert(numBuffers() == objvecvec.size()); + for (unsigned int buffer = 0; buffer < numBuffers(); buffer++) { + assert(buffers_[buffer].numEntries() == 0); // should be empty + for (auto& obj : objvec) { + if (debug_) { + dbgCout() << "Buffer " << buffer << ": add obj with pt = " << obj.intPt() << std::endl; + } + auto glbphi = sectors_[buffer].hwGlbPhiOf(obj).to_int(); + auto glbeta = sectors_[buffer].hwGlbEtaOf(obj).to_int(); + if (debug_) { + dbgCout() << "Buffer " << buffer << ": add obj with pt = " << obj.intPt() + << ", glb eta = " << glbeta << ". glb phi = " << gblphi << std::endl; + } + // get the SR indices that this object should go into + buffers_[buffer].addEntry(obj, + getSmallRegions(glbeta, glbphi), + glbeta, + glbphi); + } + } +} + +// sr is physical +template +void l1ct::tdr_alt_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntry&& bufEntry) { + auto rawObj = bufEntry.obj(); + + // in small region, the relative eta and phi are based on a different center, so need to update + auto etaC = regions_[sr].intEtaCenter(); + auto phiC = regions_[sr].intPhiCenter(); + + int locEta = bufEntry.glbEta() - etaC; + int locPhi = phi_wrap(bufEntry.glbPhi() - phiC); + + rawObj.hwEta = locEta; + rawObj.hwPhi = locPhi; + + smallRegionObjects_[sr].push_back(rawObj); +} + +// This is a dummy, should never be used. +template +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t) const { + std::vector retval; + throw cms::Exception("LogicError") << "This should be customized per type."; + return retval; +} + +template <> +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { + std::pair logic_sr = get_small_region(sr); + std::vector retval; + if (ieta < 3) { + auto nom = iphi; + auto smaller = (nom == 0) ? 8 : nom - 1; + auto bigger = (nom == 8) ? 0 : nom + 1; + retval.push_back(nom); + retval.push_back(smaller); + retval.push_back(bigger); + if (iphi == 2) { + // also add the other ones + retval.push_back(nom + 9); + retval.push_back(smaller + 9); + retval.push_back(bigger + 9) + } + } else { + auto nom = iphi + 9; + auto smaller = (nom == 9) ? 17 : nom - 1; + auto bigger = (nom == 17) ? 9 : nom + 1; + retval.push_back(nom); + retval.push_back(smaller); + retval.push_back(bigger); + if (iphi == 3) { + // also add the other ones + retval.push_back(nom - 9); + retval.push_back(smaller - 9); + retval.push_back(bigger - 9); + } + } + return retval; +} + +std::vector calo_links(size_t iphi) { + if (iphi == 0) { + std::vector retval = {1}; + return retval; + } else if (iphi < 3) { + std::vector retval = {1, 2}; + return retval; + } else if (iphi == 3) { + std::vector retval = {2}; + return retval; + } else if (iphi < 6) { + std::vector retval = {0, 2}; + return retval; + } else if (iphi == 6) { + std::vector retval = {0}; + return retval; + } else { + std::vector retval = {0, 1}; + return retval; + } +} + +template <> +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { + const std::pair logic_sr = get_small_region(sr); + return calo_links(logic_sr.second); +} + +template <> +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { + const std::pair logic_sr = get_small_region(sr); + return calo_links(logic_sr.second); +} + +template <> +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t) const { + std::vector retval = {0}; + return retval; +} + +// This is a port of: +// function get_small_region(index : linear_small_region_t) return eta_phi_small_region_t is +// variable rval : eta_phi_small_region_t; +// begin +// rval.eta_index := index / SMALL_REGION_PHI_COUNT; +// rval.phi_index := index rem SMALL_REGION_PHI_COUNT; +// return rval; +// end function get_small_region; +template +std::pair l1ct::tdr_alt_regionizer::Regionizer::get_small_region(size_t sr) const { + std::pair rval; + rval.first = sr / SMALL_REGION_PHI_COUNT; + rval.second = sr % SMALL_REGION_PHI_COUNT; + return rval; +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::run() { + if (debug_) + printDebug(-1); + + for (size_t sr = 0; sr < regionmap_.size(); sr++) { + // iterate over the (logical) SRs + auto links = linksForSR(sr); // these are the logical links + auto physSR = regionmap_[sr]; + bool allEmpty; + unsigned int count = 0; + do { + allEmpty = true + for (auto link : links) { + auto &buffer = buffer_[sectorMapLogToPhys_(link)] + if (!buffer.empty(physSR)) { + allEmpty = false; + addToSmallRegion(physSR, buffer.getEntry(physSR); + } + } + } while (!allEmpty); + } + if (debug_) + printDebug(1); +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::reset() { + for (auto& buffer : buffers_) { + buffer.reset(); + } + clearSmallRegions(); +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::clearSmallRegions() { + for (auto& smallRegionObject : smallRegionObjects_) { + smallRegionObject.clear(); + } +} + +template +void l1ct::tdr_alt_regionizer::Regionizer::printDebug(int count) const { + dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl; + dbgCout() << count << "\tbuffer\tregion\titem\tpt\teta\tphi\t" << std::endl; + for (auto sector : sectorMapLogToPhys_) { + for (auto srq_it = buffers_[sector].data_.rbegin(); srq_it != buffers_[sector].data_.rend(); ++srq_it) { + for (unsigned int j = 0; j < srq_it->size(); j++) { + dbgCout() << "\t" << sector << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() + << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } + } + + dbgCout() << "SMALL REGIONS" << std::endl; + for (unsigned int region = 0; region < neta_ * nphi_; region++) { + dbgCout() << count << "\tregion\t\titem\tpt\tloceta\tlocphi" << std::endl; + auto realRegIdx = regionIndex(region); + auto etaC = regions_[realRegIdx].intEtaCenter(); + auto phiC = regions_[realRegIdx].intPhiCenter(); + for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) { + dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" + << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t" + << smallRegionObjects_[region][j].intPhi() << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } + dbgCout() << "\n-------------------------------" << std::endl; +} + +// returns 2D arrays, sectors (links) first dimension, objects second +template +std::vector> l1ct::tdr_alt_regionizer::Regionizer::fillLinks( + const std::vector>& sectors) const { + std::vector> links; + + if (maxobjects_ == 0) { + return links; + } + //one link per sector + for (const auto& sector : sectors) { + links.emplace_back(); + for (unsigned int io = 0; io < sector.size(); io++) { + links.back().push_back(sector[io]); + } + } + + return links; +} + +template +std::vector> l1ct::tdr_alt_regionizer::Regionizer::fillLinks(const DetectorSector& sector) const { + std::vector> links; + + if (maxobjects_ == 0) { + return links; + } + + links.emplace_back(); + for (unsigned int io = 0; io < sector.size(); io++) { + links.back().push_back(sector[io]); + } + return links; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h new file mode 100644 index 0000000000000..72e55dc5e3a9b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h @@ -0,0 +1,48 @@ +#ifndef tdr_alt_regionizer_ref_h +#define tdr_alt_regionizer_ref_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h" + +// This is the second, alternate implementation of the TDR regionizer, which doesn't use a pipe for overlaps + + +namespace edm { + class ParameterSet; + class ParameterSetDescription; +} // namespace edm + +namespace l1ct { + class TDRAltRegionizerEmulator : public RegionizerEmulator { + public: + TDRAltRegionizerEmulator(uint32_t ntk, + uint32_t ncalo, + uint32_t nem, + uint32_t nmu); + + // note: this one will work only in CMSSW + TDRAltRegionizerEmulator(const edm::ParameterSet& iConfig); + + ~TDRAltRegionizerEmulator() override; + + static edm::ParameterSetDescription getParameterSetDescription(); + + void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; + + void run(const RegionizerDecodedInputs& in, std::vector& out) override; + + private: + /// The maximum number of objects of each type to output per small region + uint32_t ntk_, ncalo_, nem_, nmu_; + + bool init_; // has initialization happened + + tdr_alt_regionizer::Regionizer tkRegionizers_; + tdr_alt_regionizer::Regionizer hadCaloRegionizers_; + tdr_alt_regionizer::Regionizer emCaloRegionizers_; + tdr_alt_regionizer::Regionizer muRegionizers_; + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp new file mode 100644 index 0000000000000..016a072e2884e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp @@ -0,0 +1,122 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc" + +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +l1ct::TDRAltRegionizerEmulator::TDRAltRegionizerEmulator(const edm::ParameterSet& iConfig) + : TDRAltRegionizerEmulator(iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nEmCalo"), + iConfig.getParameter("nMu"), + iConfig.getUntrackedParameter("debug_tk"), + iConfig.getUntrackedParameter("debug_calo"), + iConfig.getUntrackedParameter("debug_emcalo"), + iConfig.getUntrackedParameter("debug_mu") + ) { + debug_ = iConfig.getUntrackedParameter("debug"); +} + +edm::ParameterSetDescription l1ct::TDRAltRegionizerEmulator::getParameterSetDescription() { + edm::ParameterSetDescription description; + description.add("nTrack", 22); + description.add("nCalo", 15); + description.add("nEmCalo", 12); + description.add("nMu", 2); + description.addUntracked("debug", false); + description.addUntracked("debug_tk", false); + description.addUntracked("debug_calo", false); + description.addUntracked("debug_emcalo", false); + description.addUntracked("debug_mu", false); + return description; +} +#endif + +l1ct::TDRAltRegionizerEmulator::TDRAltRegionizerEmulator(uint32_t ntk, + uint32_t ncalo, + uint32_t nem, + uint32_t nmu, + bool debug_tk = false, + bool debug_calo = false, + bool debug_emcalo = false, + bool debug_mu = false + ) + : RegionizerEmulator(), + ntk_(ntk), + ncalo_(ncalo), + nem_(nem), + nmu_(nmu), + init_(false), + tkRegionizers_(ntk, debug_tk), + hadCaloRegionizers_(ncalo, debug_calo), + emCaloRegionizers_(nem, debug_emcalo), + muRegionizers_(nmu, debug_mu) {} + +l1ct::TDRAltRegionizerEmulator::~TDRAltRegionizerEmulator() {} + +void l1ct::TDRAltRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, + const std::vector& out) { + if (debug_) { + dbgCout() << "doing init, out_size = " << out.size() << std::endl; + } + assert(!init_); + init_ = true; + + + if (debug_) { + dbgCout() << "in.track.size() = " << in.track.size() << std::endl; + dbgCout() << "in.hadcalo.size() = " << in.hadcalo.size() << std::endl; + dbgCout() << "in.emcalo.size() = " << in.emcalo.size() << std::endl; + } + + tkRegionizers_.initSectors(in.track); + tkRegionizers_.initRegions(out); + hadCaloRegionizers_.initSectors(in.hadcalo); + hadCaloRegionizers_.initRegions(out); + emCaloRegionizers_.initSectors(in.emcalo); + emCaloRegionizers_.initRegions(out); +} + +void l1ct::TDRAltRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + if (debug_) { + dbgCout() << "TDRAltRegionizerEmulator::run called, out.size = " << out.size() << std::endl; + } + + if (!init_) { + initSectorsAndRegions(in, out); + } + + //add objects from link + tkRegionizers_.fillBuffers(in.track); + tkRegionizers_.run(); + + emCaloRegionizers_.fillBuffers(in.emcalo); + emCaloRegionizers_.run(); + + hadCaloRegionizers_.fillBuffers(in.hadcalo); + hadCaloRegionizers_.run(); + + muRegionizers_.fillBuffers(in.muon); + muRegionizers_.run(); + + + auto trackSRs = tkRegionizers_.smallRegions(); + auto emCaloSRs = emCaloRegionizers_.smallRegions(); + auto hadCaloSRs = hadCaloRegionizers_.smallRegions(); + auto muSRs = muRegionizers_.smallRegions(); + + for (size_t sr = 0; sr < trackSRs.size(); sr++) { + out[sr].track = trackSRs[sr]; + out[sr].emcalo = emCaloSRs[sr]; + out[sr].hadcalo = hadCaloSRs[sr]; + out[sr].muon = muSRs[sr]; + } + + tkRegionizers_.clearSmallRegions(); + emCaloRegionizers_.clearSmallRegions(); + hadCaloRegionizers_.clearSmallRegions(); + muRegionizers_.clearSmallRegions(); +} From ff9b97c0e890706fd0d4534cea14cb6480582283 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Sun, 11 Jan 2026 01:26:01 -0600 Subject: [PATCH 17/92] fix compilation issues --- .../tdr_alt_regionizer_elements_ref.h | 9 +-- .../tdr_alt_regionizer_elements_ref.icc | 74 +++++++++++-------- .../regionizer/tdr_alt_regionizer_ref.h | 6 +- .../src/regionizer/tdr_alt_regionizer_ref.cpp | 8 +- 4 files changed, 57 insertions(+), 40 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h index 259b7829707fd..cc133b4554aa5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -36,7 +36,6 @@ namespace l1ct { //T obj() { return obj_; } const T& obj() const { return obj_; } - const T private: T obj_; @@ -48,7 +47,7 @@ namespace l1ct { template class Buffer { public: - Buffer() : {} + Buffer() {} void addEntry(const T& obj, std::vector srs, @@ -58,8 +57,6 @@ namespace l1ct { bool empty(size_t sr) const; BufferEntry getEntry(size_t sr); - - // mainly for debug/validation, to check that nothing is left over after an event // This is the number of entries in all the deques, not necessarily the number of // entries in the map. @@ -67,6 +64,8 @@ namespace l1ct { void reset() { data_.clear(); } + void printDebug(size_t bufIdx) const; + private: /// The actual data, indexed by the physical SR @@ -92,7 +91,7 @@ namespace l1ct { void reset(); - const std::vector>& smallRegions() const return {smallRegionObjects_; } + const std::vector>& smallRegions() const { return smallRegionObjects_; } void clearSmallRegions(); void printDebug(int count) const; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index daaead0cdd6e7..71f58d2987bfc 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -17,14 +17,43 @@ inline void l1ct::tdr_alt_regionizer::Buffer::addEntry(const T& obj, std::vec } } +template +inline bool l1ct::tdr_alt_regionizer::Buffer::empty(size_t sr) const { + auto it = data_.find(sr); + if (it != data_.end()) { + return it->second.empty(); + } else { + return true; + } +} + +template +inline l1ct::tdr_alt_regionizer::BufferEntry l1ct::tdr_alt_regionizer::Buffer::getEntry(size_t sr) { + BufferEntry entry = data_[sr].front(); + data_[sr].pop_front(); + return entry; +} + +template unsigned int l1ct::tdr_alt_regionizer::Buffer::numEntries() const { - unsinged int count = 0; + unsigned int count = 0; for (const auto& [key, value] : data_) { count += value.size(); } return count; } +template +void l1ct::tdr_alt_regionizer::Buffer::printDebug(size_t bufferIdx) const { + for (auto srq_it = data_.rbegin(); srq_it != data_.rend(); ++srq_it) { + for (unsigned int j = 0; j < srq_it->second.size(); j++) { + dbgCout() << "\t" << bufferIdx << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() + << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } +} + // REGIONIZER template l1ct::tdr_alt_regionizer::Regionizer::Regionizer(unsigned int maxobjects, @@ -50,13 +79,13 @@ void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const std::vectorsortSectors(a, b); }); // now logical to physical mapping should be correct - + if (debug_) { for (auto val : sectorMapLogToPhys_) { dbgCout() << "sectorMapLogToPhys phys index = " << val << ", eta = " << sectors_[val].intEtaCenter() @@ -78,7 +107,7 @@ void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const DetectorSector::sortRegionsHelper(int etaa, int et return false; } - // if here, then etaa == etab, move to phi - if (bigRegionMax_ < bigRegionMin_) { - // the wraparound case, rewrap around pi - if (phia < 0) { - phia += l1ct::Scales::INTPHI_TWOPI; - } - if (phib < 0) { - phib += l1ct::Scales::INTPHI_TWOPI; - } - } // regular phi if (phia < phib) { return true; @@ -191,15 +210,15 @@ void l1ct::tdr_alt_regionizer::Regionizer::setBuffers(const std::vectorsize(); j++) { - dbgCout() << "\t" << sector << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() - << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() << std::endl; - } - dbgCout() << "-------------------------------" << std::endl; - } + buffers_[sector].printDebug(sector); } dbgCout() << "SMALL REGIONS" << std::endl; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h index 72e55dc5e3a9b..7fe1454aa9fe7 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h @@ -18,7 +18,11 @@ namespace l1ct { TDRAltRegionizerEmulator(uint32_t ntk, uint32_t ncalo, uint32_t nem, - uint32_t nmu); + uint32_t nmu, + bool debug_tk = false, + bool debug_calo = false, + bool debug_emcalo = false, + bool debug_mu = false); // note: this one will work only in CMSSW TDRAltRegionizerEmulator(const edm::ParameterSet& iConfig); diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp index 016a072e2884e..d5f7c22de3acc 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp @@ -39,10 +39,10 @@ l1ct::TDRAltRegionizerEmulator::TDRAltRegionizerEmulator(uint32_t ntk, uint32_t ncalo, uint32_t nem, uint32_t nmu, - bool debug_tk = false, - bool debug_calo = false, - bool debug_emcalo = false, - bool debug_mu = false + bool debug_tk, + bool debug_calo, + bool debug_emcalo, + bool debug_mu ) : RegionizerEmulator(), ntk_(ntk), From b4070ac8ec39aa8b86697912387ae1c7b4f9c367 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Wed, 21 Jan 2026 14:25:48 +0100 Subject: [PATCH 18/92] testing new EM and PF digi cluster collection for TMI18 --- .../DigitizedCaloToCorrelatorTMI18.h | 61 ++++ .../interface/DigitizedClusterCorrelator.h | 161 ++++---- .../interface/DigitizedL1CaloJet.h | 108 ++++++ .../interface/GCTEmDigiCluster.h | 146 +++++--- .../interface/GCTHadDigiCluster.h | 57 ++- .../L1TCalorimeterPhase2/src/classes.h | 2 + .../L1TCalorimeterPhase2/src/classes_def.xml | 12 + .../interface/Phase2L1CaloEGammaUtils.h | 46 ++- .../interface/Phase2L1CaloToCorrelatorTMI18.h | 55 +++ .../plugins/Phase2L1CaloToCorrelatorTMI18.cc | 344 ++++++++++++++++++ .../Phase2L1TCaloBarrelToCorrelator.cc | 142 ++++---- .../l1tPhase2CaloToCorrelatorTMI18_cfi.py | 6 + 12 files changed, 897 insertions(+), 243 deletions(-) create mode 100644 DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h create mode 100644 DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h create mode 100644 L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h create mode 100644 L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc create mode 100644 L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h new file mode 100644 index 0000000000000..d9ca677c65b3b --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h @@ -0,0 +1,61 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTMI18_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTMI18_h + +#include +#include +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" + +namespace l1tp2 { + + typedef std::variant GCTDigiCluster; + typedef std::vector GCTDigiClusterLink; + + class DigitizedCaloToCorrelatorTMI18 { + private: + // Data + ap_uint<64> Card0Data[162] ; + ap_uint<64> Card1Data[162] ; + ap_uint<64> Card2Data[162] ; + + GCTDigiClusterLink Card0Link; + GCTDigiClusterLink Card1Link; + GCTDigiClusterLink Card2Link; + + public: + + DigitizedCaloToCorrelatorTMI18() { + for (int i = 0; i < 162; i++) { + Card0Data[i]=0; + Card1Data[i]=0; + Card2Data[i]=0; + } + } + DigitizedCaloToCorrelatorTMI18(ap_uint<64> data0[162], ap_uint<64> data1[162], ap_uint<64> data2[162], GCTDigiClusterLink link0, GCTDigiClusterLink link1, GCTDigiClusterLink link2) { + for (int i = 0; i < 162; i++) { + Card0Data[i]=data0[i]; + Card1Data[i]=data1[i]; + Card2Data[i]=data2[i]; + } + Card0Link = link0; + Card1Link = link1; + Card2Link = link2; + } + + const ap_uint<64>* dataCard0() const { return Card0Data; } + const ap_uint<64>* dataCard1() const { return Card1Data; } + const ap_uint<64>* dataCard2() const { return Card2Data; } + const GCTDigiClusterLink& linkCard0() const { return Card0Link; } + const GCTDigiClusterLink& linkCard1() const { return Card1Link; } + const GCTDigiClusterLink& linkCard2() const { return Card2Link; } + + }; + + // Collection typedef + // this represents both the EM and PF clusters from a single GCT card in one link + typedef std::vector DigitizedCaloToCorrelatorCollectionTMI18; + +} // namespace l1tp2 + +#endif diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h index 5b24441295f3d..01e960918b449 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h @@ -25,10 +25,11 @@ namespace l1tp2 { static constexpr unsigned int n_bits_unused_start = 63; // unused bits start at bit 63 // "top" of the correlator card #0 in GCT coordinates is iPhi tower index 24 - static constexpr int correlatorCard0_tower_iphi_offset = 24; + // Pallabi: changed offset values to correctly calculate realPhi() following L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h + static constexpr int correlatorCard0_tower_iphi_offset = 20; // same but for correlator cards #1 and 2 (cards wrap around phi = 180 degrees): - static constexpr int correlatorCard1_tower_iphi_offset = 48; - static constexpr int correlatorCard2_tower_iphi_offset = 0; + static constexpr int correlatorCard1_tower_iphi_offset = 44; + static constexpr int correlatorCard2_tower_iphi_offset = 68; // Private member functions to perform digitization ap_uint<12> digitizePt(float pt_f) { @@ -41,29 +42,28 @@ namespace l1tp2 { return (ap_uint<12>)(pt_f / LSB_PT); } - ap_uint<8> digitizeIEtaCr(unsigned int iEtaCr) { return (ap_uint<8>)iEtaCr; } + ap_uint<7> digitizeEta(unsigned int iEtaCr) { return (ap_uint<7>)iEtaCr; } - ap_uint<7> digitizeIPhiCr(unsigned int iPhiCr) { return (ap_uint<7>)iPhiCr; } + ap_uint<7> digitizePhi(unsigned int iPhiCr) { return (ap_uint<7>)iPhiCr; } // To-do: HoE is not defined for clusters - ap_uint<4> digitizeHoE(unsigned int hoe) { return (ap_uint<4>)hoe; } - ap_uint<2> digitizeHoeFlag(unsigned int hoeFlag) { return (ap_uint<2>)hoeFlag; } + ap_uint<6> digitizeHoE(unsigned int hoe) { return (ap_uint<6>)hoe; } - ap_uint<3> digitizeIso(unsigned int iso) { return (ap_uint<3>)iso; } - ap_uint<2> digitizeIsoFlag(unsigned int isoFlag) { return (ap_uint<2>)isoFlag; } + ap_uint<6> digitizeIso(unsigned int iso) { return (ap_uint<6>)iso; } + ap_uint<6> digitizeShape(unsigned int shape) { return (ap_uint<6>)shape; } - // To-do: fb: no information yet - ap_uint<6> digitizeFb(unsigned int fb) { return (ap_uint<6>)fb; } + // To-do: WP: no information yet + ap_uint<3> digitizeWP(unsigned int wp) { return (ap_uint<3>)wp; } // To-do: timing: no information yet ap_uint<5> digitizeTiming(unsigned int timing) { return (ap_uint<5>)timing; } - // Shape: shower shape working point - ap_uint<2> digitizeShapeFlag(unsigned int shapeFlag) { return (ap_uint<2>)shapeFlag; } - // TO-DO: Brems: was brems applied (NOT STORED YET IN GCT) ap_uint<2> digitizeBrems(unsigned int brems) { return (ap_uint<2>)brems; } + // TO-DO: Spare + ap_uint<10> digitizeSpare(unsigned int spare) { return (ap_uint<10>)spare; } + public: DigitizedClusterCorrelator() { clusterData = 0x0; } @@ -71,45 +71,22 @@ namespace l1tp2 { // Constructor from digitized inputs DigitizedClusterCorrelator(ap_uint<12> pt, - ap_uint<8> etaCr, - ap_uint<7> phiCr, - ap_uint<4> hoe, - ap_uint<2> hoeFlag, - ap_uint<3> iso, - ap_uint<2> isoFlag, - ap_uint<6> fb, + ap_uint<7> eta, + ap_int<7> phi, + ap_uint<6> hoe, + ap_uint<6> iso, + ap_uint<6> shape, + ap_uint<3> wp, ap_uint<5> timing, - ap_uint<2> shapeFlag, ap_uint<2> brems, + ap_uint<10> spare, int iGCTCard, bool fullydigitizedInputs) { - (void)fullydigitizedInputs; - clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)etaCr) << 12) | (((ap_uint<64>)phiCr) << 20) | - (((ap_uint<64>)hoe) << 27) | (((ap_uint<64>)hoeFlag) << 31) | (((ap_uint<64>)iso) << 36) | - (((ap_uint<64>)isoFlag) << 38) | (((ap_uint<64>)fb) << 44) | (((ap_uint<64>)timing) << 49) | - (((ap_uint<64>)shapeFlag << 51)) | (((ap_uint<64>)brems << 53)); - idxGCTCard = iGCTCard; - } - - // Constructor from float inputs - DigitizedClusterCorrelator(float pt_f, - unsigned int iEtaCr, - unsigned int iPhiCr, - unsigned int hoe, - unsigned int hoeFlag, - unsigned int iso, - unsigned int isoFlag, - unsigned int fb, - unsigned int timing, - unsigned int shapeFlag, - unsigned int brems, - int iGCTCard) { - clusterData = (((ap_uint<64>)digitizePt(pt_f)) | ((ap_uint<64>)digitizeIEtaCr(iEtaCr) << 12) | - ((ap_uint<64>)digitizeIPhiCr(iPhiCr) << 20) | ((ap_uint<64>)digitizeHoE(hoe) << 27) | - ((ap_uint<64>)digitizeHoeFlag(hoeFlag) << 31) | ((ap_uint<64>)digitizeIso(iso) << 36) | - ((ap_uint<64>)digitizeIsoFlag(isoFlag) << 38) | ((ap_uint<64>)digitizeFb(fb) << 44) | - ((ap_uint<64>)digitizeTiming(timing) << 49) | ((ap_uint<64>)digitizeShapeFlag(shapeFlag) << 51) | - ((ap_uint<64>)digitizeBrems(brems) << 53)); + (void)fullydigitizedInputs; // what is this? + clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)(phi & 0x7F)) << 19) | + (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | + (((ap_uint<64>)shape) << 38) | (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | + (((ap_uint<64>)brems) << 52) | (((ap_uint<64>)spare) << 54); idxGCTCard = iGCTCard; } @@ -121,45 +98,33 @@ namespace l1tp2 { float ptFloat() const { return (pt() * ptLSB()); } // crystal eta in the correlator region (LSB: 2.8/170) - ap_uint<8> eta() const { return ((clusterData >> 12) & 0xFF); } // (eight 1's) 0b11111111 = 0xFF + ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // (eight 1's) 0b11111111 = 0xFF // not eight but seven? // crystal phi in the correlator region (LSB: 2pi/360) - ap_uint<7> phi() const { return ((clusterData >> 20) & 0x7F); } // (seven 1's) 0b1111111 = 0x7F + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } // (seven 1's) 0b1111111 = 0x7F - // HoE value and flag: not defined yet in the emulator - ap_uint<4> hoe() const { return ((clusterData >> 27) & 0xF); } // (four 1's) 0b1111 = 0xF - ap_uint<2> hoeFlag() const { return ((clusterData >> 31) & 0x3); } // (two 1's) 0b11 = 0x3 + // HoE value and flag: not defined yet in the emulator + ap_uint<6> hoe() const { return ((clusterData >> 26) & 0x3F); } // (four 1's) 0b1111 = 0xF // split 6 bits in 4 and 2? // Raw isolation sum: not saved in the emulator - ap_uint<3> iso() const { return ((clusterData >> 36) & 0x7); } - - // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) - // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass - ap_uint<2> isoFlags() const { return ((clusterData >> 38) & 0x3); } // (two 1's) 0b11 = 0x3 - bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP - bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP + ap_uint<6> iso() const { return ((clusterData >> 32) & 0x3F); } // split 6 bits in 4 and 2? passes_iso and passes_looseTkiso defined in emulator? - // fb and timing: not saved in the current emulator - ap_uint<6> fb() const { return ((clusterData >> 44) & 0x3F); } - ap_uint<5> timing() const { return ((clusterData >> 49) & 0x1F); } + ap_uint<6> shape() const { return ((clusterData >> 38) & 0x3F); } // shape flags not defined? - // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP - // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass - ap_uint<2> shapeFlags() const { return ((clusterData >> 51) & 0x3); } + // wp: not saved in the current emulator + ap_uint<3> wp() const { return ((clusterData >> 44) & 0x7); } //passes_iso and passes_looseTkiso defined in emulator? - bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP - bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP + // timing: not saved in the current emulator + ap_uint<5> timing() const { return ((clusterData >> 47) & 0x1F); } // brems: not saved in the current emulator - ap_uint<2> brems() const { return ((clusterData >> 53) & 0x3); } - - // which GCT card (0, 1, or 2) - unsigned int cardNumber() const { return idxGCTCard; } + ap_uint<2> brems() const { return ((clusterData >> 52) & 0x3); } - const int unusedBitsStart() const { return n_bits_unused_start; } + ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } - // Other checks - bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); } + // which GCT card (0, 1, or 2) + // Pallabi: this is currently set incorrectly in L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloEGammaEmulator.cc so only use it to get realPhi() + //unsigned int cardNumber() const { return idxGCTCard; } // Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841. // LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta @@ -169,18 +134,48 @@ namespace l1tp2 { float realPhi() const { // each card starts at a different real phi int offset_tower = 0; - if (cardNumber() == 0) { + if (idxGCTCard == 0) { offset_tower = correlatorCard0_tower_iphi_offset; - } else if (cardNumber() == 1) { + } else if (idxGCTCard == 1) { offset_tower = correlatorCard1_tower_iphi_offset; - } else if (cardNumber() == 2) { + } else if (idxGCTCard == 2) { offset_tower = correlatorCard2_tower_iphi_offset; } - int thisPhi = (phi() + (offset_tower * n_crystals_in_tower)); - // crystal iPhi = 0 starts at real phi = -180 degrees - // LSB_PHI/2 is to add half a crystal width to get the center of the crystal in phi - return (float)((-1 * M_PI) + (thisPhi * LSB_PHI) + (LSB_PHI / 2)); + + int thisPhi = (phi() + 30); // add back the offset from L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h + int tmpphi = thisPhi; + bool wrapped = ((spare() & 0x2) == 0); + if (wrapped) { tmpphi = thisPhi + 60; } // add back the offset from L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h + int crPhi = phi() % 5; + if (phi() < 0) crPhi = (30 + phi()) % 5; + int towPhi = (tmpphi - crPhi) / 5 + 4; // corrTowPhiOffset = 4 + + int iPhi_in_gctCard = (towPhi * 5) + crPhi; + int globalClusteriPhi = (offset_tower * 5 + iPhi_in_gctCard) % (5 * 72); // CRYSTALS_IN_TOWER_PHI * n_towers_phi + float size_cell = 2 * M_PI / (5 * 72); // CRYSTALS_IN_TOWER_PHI * n_towers_phi + return globalClusteriPhi * size_cell - M_PI + 0.00873; // half_crystal_size = 0.00873 } + + // which GCT card (0, 1, or 2) + unsigned int cardNumber() const { + float phiInDegrees = realPhi()* 180 / M_PI + 180; + int cardnumber = 0; + if (phiInDegrees > 160 && phiInDegrees < 280) cardnumber = 0; + if ((phiInDegrees > 280 && phiInDegrees < 360) || phiInDegrees < 40) cardnumber = 1; + if (phiInDegrees > 40 && phiInDegrees < 160) cardnumber = 2; + if (pt() == 96) std::cout< 220) slrnumber = 1; + if (cardNumber() == 1 && (phiInDegrees > 340 || phiInDegrees < 40)) slrnumber = 1; + if (cardNumber() == 2 && phiInDegrees > 100) slrnumber = 1; + return slrnumber; + } + }; // Collection typedef diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h new file mode 100644 index 0000000000000..163a1277e8866 --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h @@ -0,0 +1,108 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedL1CaloJet_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedL1CaloJet_h + +#include +#include +#include +#include +#include +#include "DataFormats/L1Trigger/interface/L1Candidate.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +namespace l1tp2 { + + class DigitizedL1CaloJet { + public: + DigitizedL1CaloJet() { jetData = 0x0; } + + DigitizedL1CaloJet(ap_uint<64> data) { jetData = data; } + + //Constructor from digitized inputs + DigitizedL1CaloJet(ap_uint<1> isValid, + ap_uint<16> pt, + ap_int<13> phi, + ap_int<14> eta) { + jetData = ((ap_uint<64>)isValid) | (((ap_uint<64>)pt) << 1) | (((ap_int<64>)phi) << 17) | + (((ap_uint<64>)eta) << 30); + } + + // Constructor from float inputs + DigitizedL1CaloJet(bool isValid_b, + float pt_f, + float phi_f, + float eta_f) { + jetData = ((ap_uint<64>)digitizeIsValid(isValid_b)) | ((ap_uint<64>)digitizePt(pt_f) << 1) | + ((ap_uint<64>)digitizePhi(phi_f) << 17) | ((ap_uint<64>)digitizeEta(eta_f) << 30); + } + + ap_uint<64> data() const { return jetData; } + + // LSB getters + float ptLSB() const { return LSB_PT; } + float phiLSB() const { return LSB_PHI; } + float etaLSB() const { return LSB_ETA; } + + // Data getters (digitized) + ap_uint<1> isValid() const { return (jetData & 1); } + ap_uint<16> pt() const { return ((jetData >> 1) & 0xFFFF); } // 16 1s = 0xFFFF + ap_int<13> phi() const { return ((jetData >> 17) & 0x1FFF); } // 13 1s = 0x1FFF + ap_int<14> eta() const { return ((jetData >> 30) & 0x3FFF); } // 14 1s = 0x3FFF + + // Data getters (floats/bools) + bool isValidBool() const { return (bool)isValid(); } + float ptFloat() const { return (pt() * ptLSB()); } + float phiFloat() const { return (phi() * phiLSB()); } + float etaFloat() const { return (eta() * etaLSB()); } + + private: + // Digitized information as one value + unsigned long long int jetData; + + // Constants + static constexpr float LSB_PT = 0.03125; + static constexpr float LSB_PHI = M_PI / 0x1000; // 2^12 = 0x1000 + static constexpr float LSB_ETA = M_PI / 0x1000; + + static constexpr unsigned int n_bits_pt = 16; + static constexpr unsigned int n_bits_phi = 13; + static constexpr unsigned int n_bits_eta = 14; + + // Private member functions for doing the digitization + ap_uint<16> digitizePt(float pt_f) { + float maxPt_f = (std::pow(2.0f, n_bits_pt) - 1) * LSB_PT; + // If pT exceeds the maximum, saturate the value + if (pt_f >= maxPt_f) { + return (ap_uint<16>)0xFFFF; // 16 1s = 0b1111111111111111 = 0xFFFF + } + return (ap_uint<16>)(pt_f / LSB_PT); + } + + ap_uint<13> digitizePhi(float phi_f) { + float maxPhi_f = (std::pow(2.0f, n_bits_phi-1) - 1) * LSB_PHI; + // If phi exceeds the maximum (very few values should), saturate the value + if (phi_f >= maxPhi_f) { + return (ap_uint<13>)0xFFF; // 12 1s in binary = 0xFFF (1 bit for sign) + } else if (phi_f <= -maxPhi_f) { + return (ap_uint<13>)-0xFFF; + } + return (ap_uint<13>)(phi_f / LSB_PHI); + } + + ap_uint<14> digitizeEta(float eta_f) { + float maxEta_f = (std::pow(2.0f, n_bits_eta-1) - 1) * LSB_ETA; + // If eta exceeds the maximum, saturate the value + if (eta_f >= maxEta_f) { + return (ap_uint<14>)0x1FFF; // 13 1s in binary = 0x1FFF (1 bit for sign) + } else if (eta_f <= -maxEta_f) { + return (ap_uint<14>)-0x1FFF; + } + return (ap_uint<14>)(eta_f / LSB_ETA); + } + + ap_uint<1> digitizeIsValid(bool isValid_b) { return (ap_uint<1>)isValid_b; } + }; + + // Concrete collection of output objects (with extra tuning information) + typedef std::vector DigitizedL1CaloJetCollection; +} // namespace l1tp2 +#endif diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h index 0a2de6867a183..90d1ad63bcdeb 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -31,35 +31,54 @@ namespace l1tp2 { GCTEmDigiCluster(ap_uint<64> data) { clusterData = data; } + //GCTEmDigiCluster(ap_uint<12> pt, + // int etaCr, + // int phiCr, + // ap_uint<4> hoe, + // ap_uint<2> hoeFlag, + // ap_uint<3> iso, + // ap_uint<2> isoFlag, + // ap_uint<6> fb, + // ap_uint<5> timing, + // ap_uint<2> shapeFlag, + // ap_uint<2> brems) { + // // To use .range() we need an ap class member + // ap_uint<64> temp_data; + // ap_uint<7> etaCrDigitized = abs(etaCr); + // ap_int<7> phiCrDigitized = phiCr; + + // temp_data.range(11, 0) = pt.range(); + // temp_data.range(18, 12) = etaCrDigitized.range(); + // temp_data.range(25, 19) = phiCrDigitized.range(); + // temp_data.range(29, 26) = hoe.range(); + // temp_data.range(31, 30) = hoeFlag.range(); + // temp_data.range(34, 32) = iso.range(); + // temp_data.range(36, 35) = isoFlag.range(); + // temp_data.range(42, 37) = fb.range(); + // temp_data.range(47, 43) = timing.range(); + // temp_data.range(49, 48) = shapeFlag.range(); + // temp_data.range(51, 50) = brems.range(); + + // clusterData = temp_data; + //} GCTEmDigiCluster(ap_uint<12> pt, - int etaCr, - int phiCr, - ap_uint<4> hoe, - ap_uint<2> hoeFlag, - ap_uint<3> iso, - ap_uint<2> isoFlag, - ap_uint<6> fb, - ap_uint<5> timing, - ap_uint<2> shapeFlag, - ap_uint<2> brems) { - // To use .range() we need an ap class member - ap_uint<64> temp_data; - ap_uint<7> etaCrDigitized = abs(etaCr); - ap_int<7> phiCrDigitized = phiCr; - - temp_data.range(11, 0) = pt.range(); - temp_data.range(18, 12) = etaCrDigitized.range(); - temp_data.range(25, 19) = phiCrDigitized.range(); - temp_data.range(29, 26) = hoe.range(); - temp_data.range(31, 30) = hoeFlag.range(); - temp_data.range(34, 32) = iso.range(); - temp_data.range(36, 35) = isoFlag.range(); - temp_data.range(42, 37) = fb.range(); - temp_data.range(47, 43) = timing.range(); - temp_data.range(49, 48) = shapeFlag.range(); - temp_data.range(51, 50) = brems.range(); - - clusterData = temp_data; + ap_uint<7> eta, + ap_int<7> phi, + ap_uint<6> hoe, + ap_uint<6> iso, + ap_uint<6> shape, + ap_uint<3> wp, + ap_uint<5> timing, + ap_uint<2> brems, + ap_uint<10> spare, + int iGCTCard, + bool fullydigitizedInputs) { + (void)fullydigitizedInputs; + //if(pt > 20) std::cout<<"GCTEmDigiCluster phi: "<)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | + (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | + (((ap_uint<64>)shape) << 38) | (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | + (((ap_uint<64>)brems << 52)) | (((ap_uint<64>)spare << 54)); } // Setters @@ -74,47 +93,58 @@ namespace l1tp2 { // Other getters float ptLSB() const { return LSB_PT; } - ap_uint<12> pt() const { return data().range(11, 0); } + //ap_uint<12> pt() const { return data().range(11, 0); } + ap_uint<12> pt() const { return (clusterData & 0xFFF); } float ptFloat() const { return pt() * ptLSB(); } // crystal eta (unsigned, 7 bits), starting at 0 at real eta = 0, and increasing in the direction of larger abs(real eta) // to convert to real eta, need to know which link this cluster is in - int eta() const { return (ap_uint<7>)data().range(18, 12); } + //int eta() const { return (ap_uint<7>)data().range(18, 12); } + ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // crystal phi (signed, 7 bits), relative to center of the SLR // to convert to real phi, need to know which SLR this cluster is in - int phi() const { return (ap_int<7>)data().range(25, 19); } + //int phi() const { return (ap_int<7>)data().range(25, 19); } + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } // HoE value and flag: not defined yet in the emulator - ap_uint<4> hoe() const { return data().range(29, 26); } - ap_uint<2> hoeFlag() const { return data().range(31, 30); } + //ap_uint<4> hoe() const { return data().range(29, 26); } + //ap_uint<2> hoeFlag() const { return data().range(31, 30); } + ap_uint<6> hoe() const { return ((clusterData >> 26) & 0x3F); } // Raw isolation sum: not saved in the emulator - ap_uint<3> iso() const { return data().range(34, 32); } - - // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) - // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass - ap_uint<2> isoFlags() const { return data().range(36, 35); } - bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP - bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP - - // fb and timing: not saved in the current emulator - ap_uint<6> fb() const { return data().range(42, 37); } - ap_uint<5> timing() const { return data().range(47, 43); } - - // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP - // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass - ap_uint<2> shapeFlags() const { return data().range(49, 48); } - - bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP - bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP - - // brems: not saved in the current emulator - ap_uint<2> brems() const { return data().range(51, 50); } - - // Check that unused bits are zero - const int unusedBitsStart() const { return n_bits_unused_start; } - bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } + //ap_uint<3> iso() const { return data().range(34, 32); } + ap_uint<6> iso() const { return ((clusterData >> 32) & 0x3F); } + +// // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) +// // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass +// ap_uint<2> isoFlags() const { return data().range(36, 35); } +// bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP +// bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP +// +// // fb and timing: not saved in the current emulator +// ap_uint<6> fb() const { return data().range(42, 37); } +// ap_uint<5> timing() const { return data().range(47, 43); } +// +// // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP +// // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass +// ap_uint<2> shapeFlags() const { return data().range(49, 48); } +// +// bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP +// bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP +// +// // brems: not saved in the current emulator +// ap_uint<2> brems() const { return data().range(51, 50); } + + ap_uint<6> shape() const { return ((clusterData >> 38) & 0x3F); } + ap_uint<3> wp() const { return ((clusterData >> 44) & 0x7); } + ap_uint<5> timing() const { return ((clusterData >> 47) & 0x1F); } + ap_uint<2> brems() const { return ((clusterData >> 52) & 0x3); } + ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } + +// // Check that unused bits are zero +// const int unusedBitsStart() const { return n_bits_unused_start; } +// bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } // Get the underlying float cluster const edm::Ref& clusterRef() const { return clusterRef_; } diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h index 3dfa4a133019e..e001f3773f417 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h @@ -23,23 +23,36 @@ namespace l1tp2 { edm::Ref clusterRef_; public: - GCTHadDigiCluster() { clusterData = 0; } + GCTHadDigiCluster() { clusterData = 0x0; } GCTHadDigiCluster(ap_uint<64> data) { clusterData = data; } // Note types of the constructor - GCTHadDigiCluster(ap_uint<12> pt, int etaCr, int phiCr, ap_uint<4> hoe) { - // To use .range() we need an ap class member - ap_uint<64> temp_data; - - ap_uint<7> etaCrDigitized = abs(etaCr); - ap_int<7> phiCrDigitized = phiCr; - - temp_data.range(11, 0) = pt.range(); - temp_data.range(18, 12) = etaCrDigitized.range(); - temp_data.range(25, 19) = phiCrDigitized.range(); - - clusterData = temp_data; + //GCTHadDigiCluster(ap_uint<12> pt, int etaCr, int phiCr, ap_uint<4> hoe) { + // // To use .range() we need an ap class member + // ap_uint<64> temp_data; + + // ap_uint<7> etaCrDigitized = abs(etaCr); + // ap_int<7> phiCrDigitized = phiCr; + + // temp_data.range(11, 0) = pt.range(); + // temp_data.range(18, 12) = etaCrDigitized.range(); + // temp_data.range(25, 19) = phiCrDigitized.range(); + + // clusterData = temp_data; + //} + GCTHadDigiCluster(ap_uint<12> pt, + ap_uint<7> eta, + ap_int<7> phi, + ap_uint<12> ecal, + ap_uint<6> fb, + ap_uint<20> spare, + int iGCTCard, + bool fullydigitizedInputs) { + (void)fullydigitizedInputs; + clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | + (((ap_uint<64>)ecal) << 26) | (((ap_uint<64>)fb) << 38) | + (((ap_uint<64>)spare << 44)); } // Setters @@ -49,17 +62,27 @@ namespace l1tp2 { // Other getters float ptLSB() const { return LSB_PT; } - ap_uint<12> pt() const { return data().range(11, 0); } + //ap_uint<12> pt() const { return data().range(11, 0); } + ap_uint<12> pt() const { return (clusterData & 0xFFF); } float ptFloat() const { return pt() * ptLSB(); } // crystal eta (unsigned 7 bits) - int eta() const { return (ap_uint<7>)data().range(18, 12); } + //int eta() const { return (ap_uint<7>)data().range(18, 12); } + ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // (eight 1's) 0b11111111 = 0xFF // crystal phi (signed 7 bits) - int phi() const { return (ap_int<7>)data().range(25, 19); } + //int phi() const { return (ap_int<7>)data().range(25, 19); } + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } // (seven 1's) 0b1111111 = 0x7F + + // timing: not saved in the current emulator + ap_uint<12> ecal() const { return ((clusterData >> 26) & 0xFFF); } + ap_uint<6> fb() const { return ((clusterData >> 38) & 0x3F); } + + // brems: not saved in the current emulator + ap_uint<10> spare() const { return ((clusterData >> 44) & 0xFFFFF); } // HoE value - ap_uint<4> hoe() const { return data().range(30, 26); } + //ap_uint<4> hoe() const { return data().range(30, 26); } // Check that unused bits are zero const int unusedBitsStart() const { return n_bits_unused_start; } diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes.h b/DataFormats/L1TCalorimeterPhase2/src/classes.h index e979982097f68..8c5f5706e8966 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes.h +++ b/DataFormats/L1TCalorimeterPhase2/src/classes.h @@ -18,3 +18,5 @@ #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/Phase2L1CaloJet.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml index d812650d64efd..e810270018bd6 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml +++ b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml @@ -77,6 +77,18 @@ + + + + + + + + + + + + diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 7c4911fb2cd85..9400a26b040af 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -33,7 +33,7 @@ namespace p2eg { static constexpr int n_towers_Phi = 72; static constexpr int n_towers_halfPhi = 36; static constexpr int n_towers_cardEta = 17; // new: equivalent to n_towers_per_link - static constexpr int n_towers_cardPhi = 4; + static constexpr int n_towers_cardPhi = 5; static constexpr int n_crystals_cardEta = (n_towers_Eta * n_towers_cardEta); static constexpr int n_crystals_cardPhi = (n_towers_Phi * n_towers_cardPhi); @@ -86,7 +86,7 @@ namespace p2eg { static constexpr int N_GCTINTERNAL_FIBERS = 64; static constexpr int N_GCTPOSITIVE_FIBERS = 32; static constexpr int N_GCTETA = 34; - static constexpr int N_GCTPHI = 32; + static constexpr int N_GCTPHI = 36; // for emulator: "top" of the GCT card in phi is tower idx 20, for GCT card #0: static constexpr int GCTCARD_0_TOWER_IPHI_OFFSET = 20; @@ -98,10 +98,10 @@ namespace p2eg { // Outputs to correlator // Fixed number of EG and PF clusters per RCT card in each output SLR - static const int N_EG_CLUSTERS_PER_RCT_CARD = 9; - static const int N_PF_CLUSTERS_PER_RCT_CARD = 12; + static const int N_EG_CLUSTERS_PER_RCT_CARD = 4; // each eta side + static const int N_PF_CLUSTERS_PER_RCT_CARD = 6; // each eta side // Height of one SLR region in phi in degrees - static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; + static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; // including overlap ////////////////////////////////////////////////////////////////////////// // RCT: indexing helper functions @@ -1256,20 +1256,30 @@ namespace p2eg { * unique to each GCT card. */ l1tp2::DigitizedClusterCorrelator createDigitizedClusterCorrelator(const int corrTowPhiOffset) const { + // Sascha eta and phi + //ap_uint<7> abseta = 0 ; + ap_uint<8> abseta = 0 ; + ap_uint<10> spare = 0 ; + if(globalClusteriEta()>85) {abseta = globalClusteriEta() - 85 ; spare = 4 ; } + else { abseta = 85 - globalClusteriEta() ; spare = 0 ; } + + ap_int<8> tmpphi = (((towPhi - corrTowPhiOffset) * CRYSTALS_IN_TOWER_PHI) + crPhi) ; + if( tmpphi < 60) {spare = spare | 3;} + else {tmpphi = tmpphi - 60 ; spare = spare | 1 ;} + ap_int<7> phivscenter = ap_int<7>(tmpphi - 30) ; + //if (et > 100) std::cout<<"createDigitizedClusterCorrelator: "<(0x3F) , + ap_uint<6>(0x3F) , + ap_uint<6>(0x3F) , + ap_uint<3>(0x7) , + ap_uint<5>(timing), + ap_uint<2>(brems), + ap_uint<10>(spare) , + nGCTCard, true ) ; } /* diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h new file mode 100644 index 0000000000000..3ca1f98e2f1ae --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h @@ -0,0 +1,55 @@ +#ifndef Phase2L1CaloToCorrelatorTMI18_H +#define Phase2L1CaloToCorrelatorTMI18_H + + +// system include files +#include +#include + + +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +//#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +#include +#include +#include +#include +#include + +#include "FWCore/Framework/interface/ESHandle.h" +//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" +//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" + +#ifdef __MAKECINT__ +// #pragma extra_include "TLorentzVector.h"; +#pragma link C++ class std::vector; +#endif + +// +// class declaration +// +using std::vector; + +#endif diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc new file mode 100644 index 0000000000000..dd4e28d1159b8 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc @@ -0,0 +1,344 @@ +/* AS */ + +// system include files +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#ifdef __MAKECINT__ +#pragma link C++ class vector+; +#endif + +// user include files +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h" + +//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" +//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" + + +class Phase2L1CaloToCorrelatorTMI18 : public edm::stream::EDProducer<> { +public: + explicit Phase2L1CaloToCorrelatorTMI18(const edm::ParameterSet&); + ~Phase2L1CaloToCorrelatorTMI18() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions&); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + edm::EDGetTokenT gctEmDigiClustersSrc_; + edm::EDGetTokenT gctHadDigiClustersSrc_; +}; + + +Phase2L1CaloToCorrelatorTMI18::Phase2L1CaloToCorrelatorTMI18( const edm::ParameterSet & cfg ) : + gctEmDigiClustersSrc_(consumes(cfg.getParameter("gctEmDigiClusters"))), + gctHadDigiClustersSrc_(consumes(cfg.getParameter("gctHadDigiClusters"))) +{ + produces("DigitizedCaloToCorrelatorTMI18"); +} + +void Phase2L1CaloToCorrelatorTMI18::produce( edm::Event& evt, const edm::EventSetup& es ) + { + using namespace edm; + std::unique_ptr caloCandsTMI18(std::make_unique()); + + int cntr03pos = 0 ; + int cntr03neg = 0 ; + int cntr01pos = 0 ; + int cntr01neg = 0 ; + + int cntr13pos = 0 ; + int cntr13neg = 0 ; + int cntr11pos = 0 ; + int cntr11neg = 0 ; + + int cntr23pos = 0 ; + int cntr23neg = 0 ; + int cntr21pos = 0 ; + int cntr21neg = 0 ; + + ap_uint<64> mydata = 0 ; + ap_uint<64> dataToCL1Card0[162] = {0} ; + ap_uint<64> dataToCL1Card1[162] = {0} ; + ap_uint<64> dataToCL1Card2[162] = {0} ; + l1tp2::GCTDigiClusterLink clusterCollCard0(162); + l1tp2::GCTDigiClusterLink clusterCollCard1(162); + l1tp2::GCTDigiClusterLink clusterCollCard2(162); + + // SLR1 and SLR3 both send 24 PFclusters each from +ve and -ve eta, total 48 words: 4x12(x64b) + + edm::Handle gctHadDigiClusters; + if(evt.getByToken(gctHadDigiClustersSrc_, gctHadDigiClusters)) { + for (int iLink = 0; iLink < 12; iLink++) { + // in order: + // GCT1 SLR3 +ve, GCT1 SLR3 -ve, GCT1 SLR1 +ve, GCT1 SLR1 -ve + // GCT2 SLR3 +ve, GCT2 SLR3 -ve, GCT2 SLR1 +ve, GCT2 SLR1 -ve + // GCT3 SLR3 +ve, GCT3 SLR3 -ve, GCT3 SLR1 +ve, GCT3 SLR1 -ve + int iGCT = (iLink/4); + // 4 RCT regions per GCT + int iRCT = iLink - iGCT*4; + // Eta: positive or negative depends on the link. If iLink is even, it is in positive eta + bool isNegativeEta = (iRCT % 2 == 1); + // SLR alternates every two links + bool isSLR3 = ((iLink % 4) < 2); + bool isSLR1 = !isSLR3; + for (const auto & cluster : (*gctHadDigiClusters).at(iLink)) { + mydata = cluster.data() ; + if (isSLR1 && isNegativeEta) goto slr1negp; + if (isSLR1 && !isNegativeEta) goto slr1posp; + if (isSLR3 && isNegativeEta) goto slr3negp; + if (isSLR3 && !isNegativeEta) goto slr3posp; + +slr3posp: ; + + if(iGCT == 0 && cntr03pos < 24){ + dataToCL1Card0[17+cntr03pos] = mydata; + clusterCollCard0[17+cntr03pos] = cluster; + cntr03pos++; + goto fillendp; + } + if(iGCT == 1 && cntr13pos < 24){ + dataToCL1Card1[17+cntr13pos] = mydata; + clusterCollCard1[17+cntr13pos] = cluster; + cntr13pos++; + goto fillendp; + } + if(iGCT == 2 && cntr23pos < 24){ + dataToCL1Card2[17+cntr23pos] = mydata; + clusterCollCard2[17+cntr23pos] = cluster; + cntr23pos++; + goto fillendp; + } + goto fillendp; + +slr3negp: ; + + if(iGCT == 0 && cntr03neg < 24){ + dataToCL1Card0[57+cntr03neg] = mydata; + clusterCollCard0[57+cntr03neg] = cluster; + cntr03neg++; + goto fillendp; + } + if(iGCT == 1 && cntr13neg < 24){ + dataToCL1Card1[57+cntr13neg] = mydata; + clusterCollCard1[57+cntr13neg] = cluster; + cntr13neg++; + goto fillendp; + } + if(iGCT == 2 && cntr23neg < 24){ + dataToCL1Card2[57+cntr23neg] = mydata; + clusterCollCard2[57+cntr23neg] = cluster; + cntr23neg++; + goto fillendp; + } + goto fillendp; + +slr1posp: ; + + if(iGCT == 0 && cntr01pos < 24){ + dataToCL1Card0[81+17+cntr01pos] = mydata; + clusterCollCard0[81+17+cntr01pos] = cluster; + cntr01pos++; + goto fillendp; + } + if(iGCT == 1 && cntr11pos < 24){ + dataToCL1Card1[81+17+cntr11pos] = mydata; + clusterCollCard1[81+17+cntr11pos] = cluster; + cntr11pos++; + goto fillendp; + } + if(iGCT == 2 && cntr21pos < 24){ + dataToCL1Card2[81+17+cntr21pos] = mydata; + clusterCollCard2[81+17+cntr21pos] = cluster; + cntr21pos++; + goto fillendp; + } + goto fillendp; + +slr1negp: ; + + if(iGCT == 0 && cntr01neg < 24){ + dataToCL1Card0[81+57+cntr01neg] = mydata; + clusterCollCard0[81+57+cntr01neg] = cluster; + cntr01neg++; + goto fillendp; + } + if(iGCT == 1 && cntr11neg < 24){ + dataToCL1Card1[81+57+cntr11neg] = mydata; + clusterCollCard1[81+57+cntr11neg] = cluster; + cntr11neg++; + goto fillendp; + } + if(iGCT == 2 && cntr21neg < 24){ + dataToCL1Card2[81+57+cntr21neg] = mydata; + clusterCollCard2[81+57+cntr21neg] = cluster; + cntr21neg++; + goto fillendp; + } + +fillendp: ; + } + } + } + + cntr03pos = 0 ; + cntr03neg = 0 ; + cntr01pos = 0 ; + cntr01neg = 0 ; + + cntr13pos = 0 ; + cntr13neg = 0 ; + cntr11pos = 0 ; + cntr11neg = 0 ; + + cntr23pos = 0 ; + cntr23neg = 0 ; + cntr21pos = 0 ; + cntr21neg = 0 ; + + edm::Handle gctEmDigiClusters; + if(evt.getByToken(gctEmDigiClustersSrc_, gctEmDigiClusters)){ + for (int iLink = 0; iLink < 12; iLink++) { + // in order: + // GCT1 SLR3 +ve, GCT1 SLR3 -ve, GCT1 SLR1 +ve, GCT1 SLR1 -ve + // GCT2 SLR3 +ve, GCT2 SLR3 -ve, GCT2 SLR1 +ve, GCT2 SLR1 -ve + // GCT3 SLR3 +ve, GCT3 SLR3 -ve, GCT3 SLR1 +ve, GCT3 SLR1 -ve + int iGCT = (iLink/4); + // 4 RCT regions per GCT + int iRCT = iLink - iGCT*4; + // Eta: positive or negative depends on the link. If iLink is even, it is in positive eta + bool isNegativeEta = (iRCT % 2 == 1); + // SLR alternates every two links + bool isSLR3 = ((iLink % 4) < 2); + bool isSLR1 = !isSLR3; + for (const auto & cluster : (*gctEmDigiClusters).at(iLink)) { + mydata = cluster.data() ; + if (isSLR1 && isNegativeEta) goto slr1neg; + if (isSLR1 && !isNegativeEta) goto slr1pos; + if (isSLR3 && isNegativeEta) goto slr3neg; + if (isSLR3 && !isNegativeEta) goto slr3pos; + +slr3pos: ; + + if(iGCT == 0 && cntr03pos < 16){ + dataToCL1Card0[1+cntr03pos] = mydata; + clusterCollCard0[1+cntr03pos] = cluster; + cntr03pos++; + goto fillend; + } + if(iGCT == 1 && cntr13pos < 16){ + dataToCL1Card1[1+cntr13pos] = mydata; + clusterCollCard1[1+cntr13pos] = cluster; + cntr13pos++; + goto fillend; + } + if(iGCT == 2 && cntr23pos < 16){ + dataToCL1Card2[1+cntr23pos] = mydata; + clusterCollCard2[1+cntr23pos] = cluster; + cntr23pos++; + goto fillend; + } + goto fillend; + +slr3neg: ; + + if(iGCT == 0 && cntr03neg < 16){ + dataToCL1Card0[41+cntr03neg] = mydata; + clusterCollCard0[41+cntr03neg] = cluster; + cntr03neg++; + goto fillend; + } + if(iGCT == 1 && cntr13neg < 16){ + dataToCL1Card1[41+cntr13neg] = mydata; + clusterCollCard1[41+cntr13neg] = cluster; + cntr13neg++; + goto fillend; + } + if(iGCT == 2 && cntr23neg < 16){ + dataToCL1Card2[41+cntr23neg] = mydata; + clusterCollCard2[41+cntr23neg] = cluster; + cntr23neg++; + goto fillend; + } + goto fillend; + +slr1pos: ; + + if(iGCT == 0 && cntr01pos < 16){ + dataToCL1Card0[81+1+cntr01pos] = mydata; + clusterCollCard0[81+1+cntr01pos] = cluster; + cntr01pos++; + goto fillend; + } + if(iGCT == 1 && cntr11pos < 16){ + dataToCL1Card1[81+1+cntr11pos] = mydata; + clusterCollCard1[81+1+cntr11pos] = cluster; + cntr11pos++; + goto fillend; + } + if(iGCT == 2 && cntr21pos < 16){ + dataToCL1Card2[81+1+cntr21pos] = mydata; + clusterCollCard2[81+1+cntr21pos] = cluster; + cntr21pos++; + goto fillend; + } + goto fillend; + +slr1neg: ; + + if(iGCT == 0 && cntr01neg < 16){ + dataToCL1Card0[81+41+cntr01neg] = mydata; + clusterCollCard0[81+41+cntr01neg] = cluster; + cntr01neg++; + goto fillend; + } + if(iGCT == 1 && cntr11neg < 16){ + dataToCL1Card1[81+41+cntr11neg] = mydata; + clusterCollCard1[81+41+cntr11neg] = cluster; + cntr11neg++ ; + goto fillend ; + } + if(iGCT == 2 && cntr21neg < 16){ + dataToCL1Card2[81+41+cntr21neg] = mydata; + clusterCollCard2[81+41+cntr21neg] = cluster; + cntr21neg++ ; + goto fillend ; + } + +fillend: ; + } + } + } + + l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18 = l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card0, dataToCL1Card1, dataToCL1Card2, clusterCollCard0, clusterCollCard1, clusterCollCard2) ; + caloCandsTMI18->push_back(l1CaloTMI18) ; + evt.put(std::move(caloCandsTMI18), "DigitizedCaloToCorrelatorTMI18"); + + } + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void Phase2L1CaloToCorrelatorTMI18::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("gctEmDigiClusters", edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters")); + desc.add("gctHadDigiClusters", edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTHadDigiClusters")); + descriptions.addWithDefaultLabel(desc); +} + +DEFINE_FWK_MODULE(Phase2L1CaloToCorrelatorTMI18); diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index 9e5d1b13bf851..c4691d19deb3c 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -149,7 +149,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E l1tp2::GCTHadDigiClusterLink buffer_had_GCT3_SLR3_negEta[4]; //***************************************************// - // Loop over the regions: in order: GCT1 SLR1, GCT1 SLR3, GCT2 SLR1, GCT2 SLR3, GCT3 SLR1, GCT3SLR3 + // Loop over the regions: in order: GCT1 SLR3, GCT1 SLR1, GCT2 SLR3, GCT2 SLR1, GCT3 SLR3, GCT3 SLR1 //***************************************************// const int nRegions = 6; @@ -163,7 +163,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Check if this cluster falls into each SLR region, i.e. if the cluster is within 120/2 = 60 degrees of the center of the SLR in phi float clusterRealPhiAsDegree = clusterIn.realPhi() * 180 / M_PI; float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); - if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 2)) { + if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region // Go from real phi to an index in the SLR // The crystal directly above the region center in phi, is iPhi 0. The crystal directly below the region center in phi, is iPhi -1. int iPhiCrystalDifference = std::floor(phiDifference); @@ -171,26 +171,20 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // For eta, the eta is already digitized, just needs to be converted from [0, +2*17*5) to [-17*5, +17*5) int temp_iEta_signed = clusterIn.eta() - (p2eg::CRYSTALS_IN_TOWER_ETA * p2eg::n_towers_per_link); - // Default value: for clusters in positive eta, values go from 0, 1, 2, 3, 4 - int iEta = temp_iEta_signed; - // If cluster is in negative eta, instead of from -5, -4, -3, -2, -1, we want 4, 3, 2, 1, 0 - if (temp_iEta_signed < 0) { - // If in negative eta, convert to an absolute value, with 0 being the crystal nearest real eta = 0 - iEta = std::abs(temp_iEta_signed + 1); - } + // Sascha eta and phi already implemented in digi collection in Phase2L1CaloEGammaUtils.h + // Need to adapt DigitizedClusterCorrelator to DigitizedClusterCorrelatorTM18 + l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), + clusterIn.eta(), + clusterIn.phi(), + ap_uint<6>(0x3F) , + ap_uint<6>(0x3F) , + ap_uint<6>(0x3F) , + ap_uint<3>(0x7) , + ap_uint<5>(0x1F), + ap_uint<2>(0x2), + ap_uint<10>(0x3FF) , + 0, true ) ; - // Initialize the new cluster and set the edm::Ref pointing to the underlying float - l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), - iEta, - iPhiCrystalDifference, - clusterIn.hoe(), - clusterIn.hoeFlag(), - clusterIn.iso(), - clusterIn.isoFlags(), - clusterIn.fb(), - clusterIn.timing(), - clusterIn.shapeFlags(), - clusterIn.brems()); // there is a 1-to-1 mapping between the original float clusters and the first step of digitization, so we can build a ref to the same cluster edm::Ref thisRef(inputGCTClusters, iCluster); clusterOut.setRef(thisRef); @@ -212,39 +206,39 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E if (iRegion == 0) { if (temp_iEta_signed < 0) { - buffer_eg_GCT1_SLR1_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT1_SLR3_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT1_SLR1_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT1_SLR3_posEta[whichRCTcard].push_back(clusterOut); } } else if (iRegion == 1) { if (temp_iEta_signed < 0) { - buffer_eg_GCT1_SLR3_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT1_SLR1_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT1_SLR3_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT1_SLR1_posEta[whichRCTcard].push_back(clusterOut); } } else if (iRegion == 2) { if (temp_iEta_signed < 0) { - buffer_eg_GCT2_SLR1_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT2_SLR3_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT2_SLR1_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT2_SLR3_posEta[whichRCTcard].push_back(clusterOut); } } else if (iRegion == 3) { if (temp_iEta_signed < 0) { - buffer_eg_GCT2_SLR3_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT2_SLR1_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT2_SLR3_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT2_SLR1_posEta[whichRCTcard].push_back(clusterOut); } } else if (iRegion == 4) { if (temp_iEta_signed < 0) { - buffer_eg_GCT3_SLR1_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT3_SLR3_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT3_SLR1_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT3_SLR3_posEta[whichRCTcard].push_back(clusterOut); } } else if (iRegion == 5) { if (temp_iEta_signed < 0) { - buffer_eg_GCT3_SLR3_negEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT3_SLR1_negEta[whichRCTcard].push_back(clusterOut); } else { - buffer_eg_GCT3_SLR3_posEta[whichRCTcard].push_back(clusterOut); + buffer_eg_GCT3_SLR1_posEta[whichRCTcard].push_back(clusterOut); } } } @@ -260,11 +254,9 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Check if this cluster falls into each GCT card float clusterRealPhiAsDegree = pfIn.clusterPhi() * 180 / M_PI; - float differenceInPhi = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); - if (std::abs(differenceInPhi) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 2)) { + float phiDifference = clusterRealPhiAsDegree - regionCentersInDegrees[iRegion]; + if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region // Go from real phi to an index in the SLR - // Calculate the distance in phi from the center of the region - float phiDifference = clusterRealPhiAsDegree - regionCentersInDegrees[iRegion]; int iPhiCrystalDifference = std::floor(phiDifference); // For PFClusters, the method clusterEta returns a float, so we need to digitize this @@ -284,17 +276,32 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E continue; } + // Sascha eta + ap_uint<7> pf_eta = (ap_uint<7>)(abs(pfIn.clusterEta()/1.45*85)) ; + + // Sascha phi + float absphi = pfIn.clusterPhi()-0.525 ; + float phivscenter = 0; + ap_int<7> pf_phi = 0; + if(absphi>=-1.575 && absphi < -0.525) { phivscenter = absphi + 1.05 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } // first 2 bits encode slr 1 or 3 + if(absphi>=-0.525 && absphi < 0.525) { phivscenter = absphi ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} + if(absphi>=0.525 && absphi < 1.575) { phivscenter = absphi - 1.05 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} // bits 3 and 4 encode the cards 0 1 3 as 0 8 16 + if(absphi>=1.575 && absphi < 2.625) { phivscenter = absphi - 2.1 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} + if(absphi>=2.625 ) { phivscenter = absphi - 3.15 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } + if(absphi<-2.625) { phivscenter = absphi + 3.15 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } + if(absphi>=-2.625 && absphi < -1.575) { phivscenter = absphi + 2.1 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } + // Initialize the new cluster - l1tp2::GCTHadDigiCluster pfOut = - l1tp2::GCTHadDigiCluster(pfIn.clusterEt() / p2eg::ECAL_LSB, // convert to integer - iEta, - iPhiCrystalDifference, - 0 // no HoE value in PF Cluster - ); + ap_uint<20> spare = 0 ; + if(temp_iEta_signed < 0) spare = 4; // 3rd bit encode PosEta + ap_uint<12> pf_et = (ap_uint<12>)(pfIn.clusterEt() / p2eg::ECAL_LSB); + l1tp2::GCTHadDigiCluster pfOut = l1tp2::GCTHadDigiCluster(pf_et, pf_eta, pf_phi, pf_et, 0x3F, spare, 0, true); + pfOut.setRef(edm::Ref(inputPFClusters, iCluster)); // Check which RCT card this falls into, ordered 0, 1, 2, 3 counting from the most negative phi (real phi or iPhi) to the most positive // so RCT card 0 is -60 to -30 degrees in phi from the center, RCT card 1 is -30 to 0 degrees in phi from the center, RCT card 2 is 0 to +30 degrees in phi from the center, RCT card 3 is +30 to +60 degrees in phi from the center + int whichRCTcard = 0; if (phiDifference < -30) { whichRCTcard = 0; @@ -308,39 +315,39 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E if (iRegion == 0) { if (temp_iEta_signed < 0) { - buffer_had_GCT1_SLR1_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT1_SLR3_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT1_SLR1_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT1_SLR3_posEta[whichRCTcard].push_back(pfOut); } } else if (iRegion == 1) { if (temp_iEta_signed < 0) { - buffer_had_GCT1_SLR3_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT1_SLR1_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT1_SLR3_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT1_SLR1_posEta[whichRCTcard].push_back(pfOut); } } else if (iRegion == 2) { if (temp_iEta_signed < 0) { - buffer_had_GCT2_SLR1_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT2_SLR3_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT2_SLR1_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT2_SLR3_posEta[whichRCTcard].push_back(pfOut); } } else if (iRegion == 3) { if (temp_iEta_signed < 0) { - buffer_had_GCT2_SLR3_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT2_SLR1_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT2_SLR3_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT2_SLR1_posEta[whichRCTcard].push_back(pfOut); } } else if (iRegion == 4) { if (temp_iEta_signed < 0) { - buffer_had_GCT3_SLR1_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT3_SLR3_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT3_SLR1_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT3_SLR3_posEta[whichRCTcard].push_back(pfOut); } } else if (iRegion == 5) { if (temp_iEta_signed < 0) { - buffer_had_GCT3_SLR3_negEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT3_SLR1_negEta[whichRCTcard].push_back(pfOut); } else { - buffer_had_GCT3_SLR3_posEta[whichRCTcard].push_back(pfOut); + buffer_had_GCT3_SLR1_posEta[whichRCTcard].push_back(pfOut); } } } @@ -414,35 +421,36 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E out_had_GCT3_SLR1_negEta.push_back(buffer_had_GCT3_SLR1_negEta[iRCT][iCluster]); out_had_GCT3_SLR3_posEta.push_back(buffer_had_GCT3_SLR3_posEta[iRCT][iCluster]); out_had_GCT3_SLR3_negEta.push_back(buffer_had_GCT3_SLR3_negEta[iRCT][iCluster]); + } } // Finally, push back the SLR containers - outputEmClusters->push_back(out_eg_GCT1_SLR1_posEta); - outputEmClusters->push_back(out_eg_GCT1_SLR1_negEta); outputEmClusters->push_back(out_eg_GCT1_SLR3_posEta); outputEmClusters->push_back(out_eg_GCT1_SLR3_negEta); - outputEmClusters->push_back(out_eg_GCT2_SLR1_posEta); - outputEmClusters->push_back(out_eg_GCT2_SLR1_negEta); + outputEmClusters->push_back(out_eg_GCT1_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT1_SLR1_negEta); outputEmClusters->push_back(out_eg_GCT2_SLR3_posEta); outputEmClusters->push_back(out_eg_GCT2_SLR3_negEta); - outputEmClusters->push_back(out_eg_GCT3_SLR1_posEta); - outputEmClusters->push_back(out_eg_GCT3_SLR1_negEta); + outputEmClusters->push_back(out_eg_GCT2_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT2_SLR1_negEta); outputEmClusters->push_back(out_eg_GCT3_SLR3_posEta); outputEmClusters->push_back(out_eg_GCT3_SLR3_negEta); + outputEmClusters->push_back(out_eg_GCT3_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT3_SLR1_negEta); - outputHadClusters->push_back(out_had_GCT1_SLR1_posEta); - outputHadClusters->push_back(out_had_GCT1_SLR1_negEta); outputHadClusters->push_back(out_had_GCT1_SLR3_posEta); outputHadClusters->push_back(out_had_GCT1_SLR3_negEta); - outputHadClusters->push_back(out_had_GCT2_SLR1_posEta); - outputHadClusters->push_back(out_had_GCT2_SLR1_negEta); + outputHadClusters->push_back(out_had_GCT1_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT1_SLR1_negEta); outputHadClusters->push_back(out_had_GCT2_SLR3_posEta); outputHadClusters->push_back(out_had_GCT2_SLR3_negEta); - outputHadClusters->push_back(out_had_GCT3_SLR1_posEta); - outputHadClusters->push_back(out_had_GCT3_SLR1_negEta); + outputHadClusters->push_back(out_had_GCT2_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT2_SLR1_negEta); outputHadClusters->push_back(out_had_GCT3_SLR3_posEta); outputHadClusters->push_back(out_had_GCT3_SLR3_negEta); + outputHadClusters->push_back(out_had_GCT3_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT3_SLR1_negEta); iEvent.put(std::move(outputEmClusters), "GCTEmDigiClusters"); iEvent.put(std::move(outputHadClusters), "GCTHadDigiClusters"); diff --git a/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py b/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py new file mode 100644 index 0000000000000..42af91b4f3956 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py @@ -0,0 +1,6 @@ +import FWCore.ParameterSet.Config as cms + +l1tPhase2CaloToCorrelatorTMI18 = cms.EDProducer("Phase2L1CaloToCorrelatorTMI18", + gctEmDigiClusters = cms.InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters"), + gctHadDigiClusters = cms.InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTHadDigiClusters"), +) From 553b374858771a29054901ff44035cba11099f88 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Mon, 2 Feb 2026 22:07:27 +0100 Subject: [PATCH 19/92] PR comments from Jovan and Gianluca --- .../interface/CaloPFCluster.h | 7 + .../DigitizedCaloToCorrelatorTMI18.h | 45 +- .../interface/DigitizedClusterCorrelator.h | 118 ++--- .../interface/DigitizedL1CaloJet.h | 36 +- .../interface/GCTEmDigiCluster.h | 105 +---- .../interface/GCTHadDigiCluster.h | 55 +-- .../L1TCalorimeterPhase2/src/classes_def.xml | 8 +- .../Phase2L1CaloBarrelToCorrelator.h | 27 -- .../interface/Phase2L1CaloEGammaUtils.h | 147 +++++-- .../interface/Phase2L1CaloPFClusterEmulator.h | 62 +-- .../interface/Phase2L1CaloToCorrelatorTMI18.h | 9 - .../L1CaloTrigger/interface/Phase2L1GCT.h | 10 +- .../plugins/Phase2L1CaloJetEmulator.cc | 4 +- .../plugins/Phase2L1CaloPFClusterEmulator.cc | 30 +- .../plugins/Phase2L1CaloToCorrelatorTMI18.cc | 416 ++++++++---------- .../Phase2L1TCaloBarrelToCorrelator.cc | 73 ++- 16 files changed, 484 insertions(+), 668 deletions(-) delete mode 100644 L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h diff --git a/DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h index 6a242e3f54939..88e0ee43a9b66 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h @@ -14,6 +14,7 @@ namespace l1tp2 { CaloPFCluster() : l1t::L1Candidate(), clusterEt_(0.), + ecalEt_(0.), clusterIEta_(-99), clusterIPhi_(-99), clusterEta_(-99.), @@ -21,23 +22,27 @@ namespace l1tp2 { CaloPFCluster(const PolarLorentzVector& p4, float clusterEt, + float ecalEt, int clusterIEta, int clusterIPhi, float clusterEta, float clusterPhi) : l1t::L1Candidate(p4), clusterEt_(clusterEt), + ecalEt_(ecalEt), clusterIEta_(clusterIEta), clusterIPhi_(clusterIPhi), clusterEta_(clusterEta), clusterPhi_(clusterPhi) {} inline float clusterEt() const { return clusterEt_; }; + inline float ecalEt() const { return ecalEt_; }; inline int clusterIEta() const { return clusterIEta_; }; inline int clusterIPhi() const { return clusterIPhi_; }; inline float clusterEta() const { return clusterEta_; }; inline float clusterPhi() const { return clusterPhi_; }; void setClusterEt(float clusterEtIn) { clusterEt_ = clusterEtIn; }; + void setEcalEt(float ecalEtIn) { ecalEt_ = ecalEtIn; }; void setClusterIEta(int clusterIEtaIn) { clusterIEta_ = clusterIEtaIn; }; void setClusterIPhi(int clusterIPhiIn) { clusterIPhi_ = clusterIPhiIn; }; void setClusterEta(float clusterEtaIn) { clusterEta_ = clusterEtaIn; }; @@ -46,6 +51,8 @@ namespace l1tp2 { private: // ET float clusterEt_; + // ECAL ET + float ecalEt_; // GCT ieta int clusterIEta_; // GCT iphi diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h index d9ca677c65b3b..2dd970bc6fd83 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h @@ -5,7 +5,6 @@ #include #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" namespace l1tp2 { @@ -14,42 +13,26 @@ namespace l1tp2 { class DigitizedCaloToCorrelatorTMI18 { private: - // Data - ap_uint<64> Card0Data[162] ; - ap_uint<64> Card1Data[162] ; - ap_uint<64> Card2Data[162] ; + // Data (to remove) + ap_uint<64> CardData[162]; - GCTDigiClusterLink Card0Link; - GCTDigiClusterLink Card1Link; - GCTDigiClusterLink Card2Link; + GCTDigiClusterLink CardLink; public: - - DigitizedCaloToCorrelatorTMI18() { - for (int i = 0; i < 162; i++) { - Card0Data[i]=0; - Card1Data[i]=0; - Card2Data[i]=0; - } + DigitizedCaloToCorrelatorTMI18() { + for (int i = 0; i < 162; i++) { + CardData[i] = 0; + } } - DigitizedCaloToCorrelatorTMI18(ap_uint<64> data0[162], ap_uint<64> data1[162], ap_uint<64> data2[162], GCTDigiClusterLink link0, GCTDigiClusterLink link1, GCTDigiClusterLink link2) { - for (int i = 0; i < 162; i++) { - Card0Data[i]=data0[i]; - Card1Data[i]=data1[i]; - Card2Data[i]=data2[i]; - } - Card0Link = link0; - Card1Link = link1; - Card2Link = link2; + DigitizedCaloToCorrelatorTMI18(ap_uint<64> data[162], GCTDigiClusterLink link) { + for (int i = 0; i < 162; i++) { + CardData[i] = data[i]; + } + CardLink = link; } - const ap_uint<64>* dataCard0() const { return Card0Data; } - const ap_uint<64>* dataCard1() const { return Card1Data; } - const ap_uint<64>* dataCard2() const { return Card2Data; } - const GCTDigiClusterLink& linkCard0() const { return Card0Link; } - const GCTDigiClusterLink& linkCard1() const { return Card1Link; } - const GCTDigiClusterLink& linkCard2() const { return Card2Link; } - + const ap_uint<64>* dataCard() const { return CardData; } + const GCTDigiClusterLink& linkCard() const { return CardLink; } }; // Collection typedef diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h index 01e960918b449..5d02c6c4a6945 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h @@ -20,49 +20,16 @@ namespace l1tp2 { static constexpr float ETA_RANGE_ONE_SIDE = 1.4841; // barrel goes from (-1.4841, +1.4841) static constexpr float LSB_ETA = ((2 * ETA_RANGE_ONE_SIDE) / (n_towers_eta * n_crystals_in_tower)); // (2.8 / 170) static constexpr float LSB_PHI = ((2 * M_PI) / (3 * n_towers_phi * n_crystals_in_tower)); // (2 pi * 360) + static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; static constexpr unsigned int n_bits_pt = 12; // 12 bits allocated for pt static constexpr unsigned int n_bits_unused_start = 63; // unused bits start at bit 63 // "top" of the correlator card #0 in GCT coordinates is iPhi tower index 24 - // Pallabi: changed offset values to correctly calculate realPhi() following L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h - static constexpr int correlatorCard0_tower_iphi_offset = 20; + static constexpr int correlatorCard0_tower_iphi_offset = 68; // same but for correlator cards #1 and 2 (cards wrap around phi = 180 degrees): - static constexpr int correlatorCard1_tower_iphi_offset = 44; - static constexpr int correlatorCard2_tower_iphi_offset = 68; - - // Private member functions to perform digitization - ap_uint<12> digitizePt(float pt_f) { - float maxPt_f = (std::pow(2, n_bits_pt) - 1) * LSB_PT; - // If pT exceeds the maximum (extremely unlikely), saturate the value - if (pt_f >= maxPt_f) { - return (ap_uint<12>)0xFFF; - } - - return (ap_uint<12>)(pt_f / LSB_PT); - } - - ap_uint<7> digitizeEta(unsigned int iEtaCr) { return (ap_uint<7>)iEtaCr; } - - ap_uint<7> digitizePhi(unsigned int iPhiCr) { return (ap_uint<7>)iPhiCr; } - - // To-do: HoE is not defined for clusters - ap_uint<6> digitizeHoE(unsigned int hoe) { return (ap_uint<6>)hoe; } - - ap_uint<6> digitizeIso(unsigned int iso) { return (ap_uint<6>)iso; } - ap_uint<6> digitizeShape(unsigned int shape) { return (ap_uint<6>)shape; } - - // To-do: WP: no information yet - ap_uint<3> digitizeWP(unsigned int wp) { return (ap_uint<3>)wp; } - - // To-do: timing: no information yet - ap_uint<5> digitizeTiming(unsigned int timing) { return (ap_uint<5>)timing; } - - // TO-DO: Brems: was brems applied (NOT STORED YET IN GCT) - ap_uint<2> digitizeBrems(unsigned int brems) { return (ap_uint<2>)brems; } - - // TO-DO: Spare - ap_uint<10> digitizeSpare(unsigned int spare) { return (ap_uint<10>)spare; } + static constexpr int correlatorCard1_tower_iphi_offset = 20; + static constexpr int correlatorCard2_tower_iphi_offset = 44; public: DigitizedClusterCorrelator() { clusterData = 0x0; } @@ -80,13 +47,11 @@ namespace l1tp2 { ap_uint<5> timing, ap_uint<2> brems, ap_uint<10> spare, - int iGCTCard, - bool fullydigitizedInputs) { - (void)fullydigitizedInputs; // what is this? + int iGCTCard) { clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)(phi & 0x7F)) << 19) | - (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | - (((ap_uint<64>)shape) << 38) | (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | - (((ap_uint<64>)brems) << 52) | (((ap_uint<64>)spare) << 54); + (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | (((ap_uint<64>)shape) << 38) | + (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | (((ap_uint<64>)brems) << 52) | + (((ap_uint<64>)spare) << 54); idxGCTCard = iGCTCard; } @@ -98,21 +63,19 @@ namespace l1tp2 { float ptFloat() const { return (pt() * ptLSB()); } // crystal eta in the correlator region (LSB: 2.8/170) - ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // (eight 1's) 0b11111111 = 0xFF // not eight but seven? + ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // (seven 1's) 0b11111111 = 0x7F // crystal phi in the correlator region (LSB: 2pi/360) - ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } // (seven 1's) 0b1111111 = 0x7F + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } - // HoE value and flag: not defined yet in the emulator - ap_uint<6> hoe() const { return ((clusterData >> 26) & 0x3F); } // (four 1's) 0b1111 = 0xF // split 6 bits in 4 and 2? + // HoE value and flag: not defined yet in the emulator + ap_uint<6> hoe() const { return ((clusterData >> 26) & 0x3F); } - // Raw isolation sum: not saved in the emulator - ap_uint<6> iso() const { return ((clusterData >> 32) & 0x3F); } // split 6 bits in 4 and 2? passes_iso and passes_looseTkiso defined in emulator? + ap_uint<6> iso() const { return ((clusterData >> 32) & 0x3F); } // raw isolation sum - ap_uint<6> shape() const { return ((clusterData >> 38) & 0x3F); } // shape flags not defined? + ap_uint<6> shape() const { return ((clusterData >> 38) & 0x3F); } // et2x5/et5x5 - // wp: not saved in the current emulator - ap_uint<3> wp() const { return ((clusterData >> 44) & 0x7); } //passes_iso and passes_looseTkiso defined in emulator? + ap_uint<3> wp() const { return ((clusterData >> 44) & 0x7); } // encoded standaloneWP, looseL1TkMatchWP, photonWP // timing: not saved in the current emulator ap_uint<5> timing() const { return ((clusterData >> 47) & 0x1F); } @@ -123,8 +86,7 @@ namespace l1tp2 { ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } // which GCT card (0, 1, or 2) - // Pallabi: this is currently set incorrectly in L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloEGammaEmulator.cc so only use it to get realPhi() - //unsigned int cardNumber() const { return idxGCTCard; } + unsigned int cardNumber() const { return idxGCTCard; } // Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841. // LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta @@ -134,48 +96,26 @@ namespace l1tp2 { float realPhi() const { // each card starts at a different real phi int offset_tower = 0; - if (idxGCTCard == 0) { + if (cardNumber() == 0) { offset_tower = correlatorCard0_tower_iphi_offset; - } else if (idxGCTCard == 1) { + } else if (cardNumber() == 1) { offset_tower = correlatorCard1_tower_iphi_offset; - } else if (idxGCTCard == 2) { + } else if (cardNumber() == 2) { offset_tower = correlatorCard2_tower_iphi_offset; } - int thisPhi = (phi() + 30); // add back the offset from L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h - int tmpphi = thisPhi; - bool wrapped = ((spare() & 0x2) == 0); - if (wrapped) { tmpphi = thisPhi + 60; } // add back the offset from L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h - int crPhi = phi() % 5; - if (phi() < 0) crPhi = (30 + phi()) % 5; - int towPhi = (tmpphi - crPhi) / 5 + 4; // corrTowPhiOffset = 4 - - int iPhi_in_gctCard = (towPhi * 5) + crPhi; - int globalClusteriPhi = (offset_tower * 5 + iPhi_in_gctCard) % (5 * 72); // CRYSTALS_IN_TOWER_PHI * n_towers_phi - float size_cell = 2 * M_PI / (5 * 72); // CRYSTALS_IN_TOWER_PHI * n_towers_phi - return globalClusteriPhi * size_cell - M_PI + 0.00873; // half_crystal_size = 0.00873 - } + int tmpphi = (phi() + PHI_RANGE_PER_SLR_DEGREES / 4); + bool wrapped = !((spare() & 0x2) == 0); + if (wrapped) { + tmpphi += PHI_RANGE_PER_SLR_DEGREES / 2; + } + int thisPhi = (tmpphi + (offset_tower * n_crystals_in_tower)); + if (thisPhi > 180) + thisPhi -= 360; // range between -180 to 180 degrees - // which GCT card (0, 1, or 2) - unsigned int cardNumber() const { - float phiInDegrees = realPhi()* 180 / M_PI + 180; - int cardnumber = 0; - if (phiInDegrees > 160 && phiInDegrees < 280) cardnumber = 0; - if ((phiInDegrees > 280 && phiInDegrees < 360) || phiInDegrees < 40) cardnumber = 1; - if (phiInDegrees > 40 && phiInDegrees < 160) cardnumber = 2; - if (pt() == 96) std::cout< 220) slrnumber = 1; - if (cardNumber() == 1 && (phiInDegrees > 340 || phiInDegrees < 40)) slrnumber = 1; - if (cardNumber() == 2 && phiInDegrees > 100) slrnumber = 1; - return slrnumber; - } - }; // Collection typedef diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h index 163a1277e8866..269dcc4001058 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h @@ -18,21 +18,15 @@ namespace l1tp2 { DigitizedL1CaloJet(ap_uint<64> data) { jetData = data; } //Constructor from digitized inputs - DigitizedL1CaloJet(ap_uint<1> isValid, - ap_uint<16> pt, - ap_int<13> phi, - ap_int<14> eta) { - jetData = ((ap_uint<64>)isValid) | (((ap_uint<64>)pt) << 1) | (((ap_int<64>)phi) << 17) | - (((ap_uint<64>)eta) << 30); + DigitizedL1CaloJet(ap_uint<1> isValid, ap_uint<16> pt, ap_int<13> phi, ap_int<14> eta) { + jetData = + ((ap_uint<64>)isValid) | (((ap_uint<64>)pt) << 1) | (((ap_int<64>)phi) << 17) | (((ap_uint<64>)eta) << 30); } // Constructor from float inputs - DigitizedL1CaloJet(bool isValid_b, - float pt_f, - float phi_f, - float eta_f) { + DigitizedL1CaloJet(bool isValid_b, float pt_f, float phi_f, float eta_f) { jetData = ((ap_uint<64>)digitizeIsValid(isValid_b)) | ((ap_uint<64>)digitizePt(pt_f) << 1) | - ((ap_uint<64>)digitizePhi(phi_f) << 17) | ((ap_uint<64>)digitizeEta(eta_f) << 30); + ((ap_uint<64>)digitizePhi(phi_f) << 17) | ((ap_uint<64>)digitizeEta(eta_f) << 30); } ap_uint<64> data() const { return jetData; } @@ -44,9 +38,9 @@ namespace l1tp2 { // Data getters (digitized) ap_uint<1> isValid() const { return (jetData & 1); } - ap_uint<16> pt() const { return ((jetData >> 1) & 0xFFFF); } // 16 1s = 0xFFFF - ap_int<13> phi() const { return ((jetData >> 17) & 0x1FFF); } // 13 1s = 0x1FFF - ap_int<14> eta() const { return ((jetData >> 30) & 0x3FFF); } // 14 1s = 0x3FFF + ap_uint<16> pt() const { return ((jetData >> 1) & 0xFFFF); } // 16 1s = 0xFFFF + ap_int<13> phi() const { return ((jetData >> 17) & 0x1FFF); } // 13 1s = 0x1FFF + ap_int<14> eta() const { return ((jetData >> 30) & 0x3FFF); } // 14 1s = 0x3FFF // Data getters (floats/bools) bool isValidBool() const { return (bool)isValid(); } @@ -57,10 +51,10 @@ namespace l1tp2 { private: // Digitized information as one value unsigned long long int jetData; - + // Constants static constexpr float LSB_PT = 0.03125; - static constexpr float LSB_PHI = M_PI / 0x1000; // 2^12 = 0x1000 + static constexpr float LSB_PHI = M_PI / 0x1000; // 2^12 = 0x1000 static constexpr float LSB_ETA = M_PI / 0x1000; static constexpr unsigned int n_bits_pt = 16; @@ -72,16 +66,16 @@ namespace l1tp2 { float maxPt_f = (std::pow(2.0f, n_bits_pt) - 1) * LSB_PT; // If pT exceeds the maximum, saturate the value if (pt_f >= maxPt_f) { - return (ap_uint<16>)0xFFFF; // 16 1s = 0b1111111111111111 = 0xFFFF + return (ap_uint<16>)0xFFFF; // 16 1s = 0b1111111111111111 = 0xFFFF } return (ap_uint<16>)(pt_f / LSB_PT); } ap_uint<13> digitizePhi(float phi_f) { - float maxPhi_f = (std::pow(2.0f, n_bits_phi-1) - 1) * LSB_PHI; + float maxPhi_f = (std::pow(2.0f, n_bits_phi - 1) - 1) * LSB_PHI; // If phi exceeds the maximum (very few values should), saturate the value if (phi_f >= maxPhi_f) { - return (ap_uint<13>)0xFFF; // 12 1s in binary = 0xFFF (1 bit for sign) + return (ap_uint<13>)0xFFF; // 12 1s in binary = 0xFFF (1 bit for sign) } else if (phi_f <= -maxPhi_f) { return (ap_uint<13>)-0xFFF; } @@ -89,10 +83,10 @@ namespace l1tp2 { } ap_uint<14> digitizeEta(float eta_f) { - float maxEta_f = (std::pow(2.0f, n_bits_eta-1) - 1) * LSB_ETA; + float maxEta_f = (std::pow(2.0f, n_bits_eta - 1) - 1) * LSB_ETA; // If eta exceeds the maximum, saturate the value if (eta_f >= maxEta_f) { - return (ap_uint<14>)0x1FFF; // 13 1s in binary = 0x1FFF (1 bit for sign) + return (ap_uint<14>)0x1FFF; // 13 1s in binary = 0x1FFF (1 bit for sign) } else if (eta_f <= -maxEta_f) { return (ap_uint<14>)-0x1FFF; } diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h index 90d1ad63bcdeb..afb45146b9e6a 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -17,9 +17,6 @@ namespace l1tp2 { // Constants static constexpr float LSB_PT = 0.5; // 0.5 GeV - // start of the unused bits - static constexpr int n_bits_unused_start = 52; - // Reference to the original float cluster edm::Ref clusterRef_; @@ -31,54 +28,20 @@ namespace l1tp2 { GCTEmDigiCluster(ap_uint<64> data) { clusterData = data; } - //GCTEmDigiCluster(ap_uint<12> pt, - // int etaCr, - // int phiCr, - // ap_uint<4> hoe, - // ap_uint<2> hoeFlag, - // ap_uint<3> iso, - // ap_uint<2> isoFlag, - // ap_uint<6> fb, - // ap_uint<5> timing, - // ap_uint<2> shapeFlag, - // ap_uint<2> brems) { - // // To use .range() we need an ap class member - // ap_uint<64> temp_data; - // ap_uint<7> etaCrDigitized = abs(etaCr); - // ap_int<7> phiCrDigitized = phiCr; - - // temp_data.range(11, 0) = pt.range(); - // temp_data.range(18, 12) = etaCrDigitized.range(); - // temp_data.range(25, 19) = phiCrDigitized.range(); - // temp_data.range(29, 26) = hoe.range(); - // temp_data.range(31, 30) = hoeFlag.range(); - // temp_data.range(34, 32) = iso.range(); - // temp_data.range(36, 35) = isoFlag.range(); - // temp_data.range(42, 37) = fb.range(); - // temp_data.range(47, 43) = timing.range(); - // temp_data.range(49, 48) = shapeFlag.range(); - // temp_data.range(51, 50) = brems.range(); - - // clusterData = temp_data; - //} GCTEmDigiCluster(ap_uint<12> pt, - ap_uint<7> eta, - ap_int<7> phi, - ap_uint<6> hoe, - ap_uint<6> iso, - ap_uint<6> shape, - ap_uint<3> wp, - ap_uint<5> timing, - ap_uint<2> brems, - ap_uint<10> spare, - int iGCTCard, - bool fullydigitizedInputs) { - (void)fullydigitizedInputs; - //if(pt > 20) std::cout<<"GCTEmDigiCluster phi: "< eta, + ap_int<7> phi, + ap_uint<6> hoe, + ap_uint<6> iso, + ap_uint<6> shape, + ap_uint<3> wp, + ap_uint<5> timing, + ap_uint<2> brems, + ap_uint<10> spare) { clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | - (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | - (((ap_uint<64>)shape) << 38) | (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | - (((ap_uint<64>)brems << 52)) | (((ap_uint<64>)spare << 54)); + (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | (((ap_uint<64>)shape) << 38) | + (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | (((ap_uint<64>)brems << 52)) | + (((ap_uint<64>)spare << 54)); } // Setters @@ -93,58 +56,36 @@ namespace l1tp2 { // Other getters float ptLSB() const { return LSB_PT; } - //ap_uint<12> pt() const { return data().range(11, 0); } ap_uint<12> pt() const { return (clusterData & 0xFFF); } float ptFloat() const { return pt() * ptLSB(); } // crystal eta (unsigned, 7 bits), starting at 0 at real eta = 0, and increasing in the direction of larger abs(real eta) // to convert to real eta, need to know which link this cluster is in - //int eta() const { return (ap_uint<7>)data().range(18, 12); } ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // crystal phi (signed, 7 bits), relative to center of the SLR // to convert to real phi, need to know which SLR this cluster is in - //int phi() const { return (ap_int<7>)data().range(25, 19); } - ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } - // HoE value and flag: not defined yet in the emulator - //ap_uint<4> hoe() const { return data().range(29, 26); } - //ap_uint<2> hoeFlag() const { return data().range(31, 30); } + // HoE value: not defined for EG cluster ap_uint<6> hoe() const { return ((clusterData >> 26) & 0x3F); } - // Raw isolation sum: not saved in the emulator - //ap_uint<3> iso() const { return data().range(34, 32); } + // Raw isolation sum ap_uint<6> iso() const { return ((clusterData >> 32) & 0x3F); } -// // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) -// // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass -// ap_uint<2> isoFlags() const { return data().range(36, 35); } -// bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP -// bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP -// -// // fb and timing: not saved in the current emulator -// ap_uint<6> fb() const { return data().range(42, 37); } -// ap_uint<5> timing() const { return data().range(47, 43); } -// -// // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP -// // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass -// ap_uint<2> shapeFlags() const { return data().range(49, 48); } -// -// bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP -// bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP -// -// // brems: not saved in the current emulator -// ap_uint<2> brems() const { return data().range(51, 50); } - + // Shape information: et2x5/et5x5 normalized to 0x3F ap_uint<6> shape() const { return ((clusterData >> 38) & 0x3F); } + + // Working points: bit 0 standaloneWP, bit 1 looseL1TkMatchWP, bit 2 photonWP ap_uint<3> wp() const { return ((clusterData >> 44) & 0x7); } + ap_uint<5> timing() const { return ((clusterData >> 47) & 0x1F); } + + // Brem information from RCT ap_uint<2> brems() const { return ((clusterData >> 52) & 0x3); } - ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } -// // Check that unused bits are zero -// const int unusedBitsStart() const { return n_bits_unused_start; } -// bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } + // Encoding region information + ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } // Get the underlying float cluster const edm::Ref& clusterRef() const { return clusterRef_; } diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h index e001f3773f417..b09073a427a1c 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h @@ -16,9 +16,6 @@ namespace l1tp2 { // Constants static constexpr float LSB_PT = 0.5; // 0.5 GeV - // start of the unused bits - static constexpr int n_bits_unused_start = 31; - // reference to corresponding float cluster edm::Ref clusterRef_; @@ -27,69 +24,37 @@ namespace l1tp2 { GCTHadDigiCluster(ap_uint<64> data) { clusterData = data; } - // Note types of the constructor - //GCTHadDigiCluster(ap_uint<12> pt, int etaCr, int phiCr, ap_uint<4> hoe) { - // // To use .range() we need an ap class member - // ap_uint<64> temp_data; - - // ap_uint<7> etaCrDigitized = abs(etaCr); - // ap_int<7> phiCrDigitized = phiCr; - - // temp_data.range(11, 0) = pt.range(); - // temp_data.range(18, 12) = etaCrDigitized.range(); - // temp_data.range(25, 19) = phiCrDigitized.range(); - - // clusterData = temp_data; - //} - GCTHadDigiCluster(ap_uint<12> pt, - ap_uint<7> eta, - ap_int<7> phi, - ap_uint<12> ecal, - ap_uint<6> fb, - ap_uint<20> spare, - int iGCTCard, - bool fullydigitizedInputs) { - (void)fullydigitizedInputs; + GCTHadDigiCluster( + ap_uint<12> pt, ap_uint<7> eta, ap_int<7> phi, ap_uint<12> ecal, ap_uint<6> fb, ap_uint<36> spare) { clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | - (((ap_uint<64>)ecal) << 26) | (((ap_uint<64>)fb) << 38) | - (((ap_uint<64>)spare << 44)); + (((ap_uint<64>)ecal) << 26) | (((ap_uint<64>)fb) << 38) | (((ap_uint<64>)spare << 44)); } // Setters - void setRef(const edm::Ref &clusterRef) { clusterRef_ = clusterRef; } + void setRef(const edm::Ref& clusterRef) { clusterRef_ = clusterRef; } // Getters ap_uint<64> data() const { return clusterData; } // Other getters float ptLSB() const { return LSB_PT; } - //ap_uint<12> pt() const { return data().range(11, 0); } ap_uint<12> pt() const { return (clusterData & 0xFFF); } float ptFloat() const { return pt() * ptLSB(); } // crystal eta (unsigned 7 bits) - //int eta() const { return (ap_uint<7>)data().range(18, 12); } - ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // (eight 1's) 0b11111111 = 0xFF + ap_uint<7> eta() const { return ((clusterData >> 12) & 0x7F); } // crystal phi (signed 7 bits) - //int phi() const { return (ap_int<7>)data().range(25, 19); } - ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } // (seven 1's) 0b1111111 = 0x7F + ap_int<7> phi() const { return ((clusterData >> 19) & 0x7F); } - // timing: not saved in the current emulator ap_uint<12> ecal() const { return ((clusterData >> 26) & 0xFFF); } - ap_uint<6> fb() const { return ((clusterData >> 38) & 0x3F); } - // brems: not saved in the current emulator - ap_uint<10> spare() const { return ((clusterData >> 44) & 0xFFFFF); } - - // HoE value - //ap_uint<4> hoe() const { return data().range(30, 26); } + ap_uint<6> fb() const { return ((clusterData >> 38) & 0x3F); } - // Check that unused bits are zero - const int unusedBitsStart() const { return n_bits_unused_start; } - bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } + // Encoding region information + ap_uint<36> spare() const { return ((clusterData >> 44) & 0xFFFFF); } // Get the underlying ref - edm::Ref clusterRef() const { return clusterRef_; } + const edm::Ref& clusterRef() const { return clusterRef_; } }; // Collection typedefs diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml index e810270018bd6..20b2fd217a8e0 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml +++ b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml @@ -19,8 +19,8 @@ - - + + @@ -84,8 +84,8 @@ - - + + diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h deleted file mode 100644 index d83cdb050a696..0000000000000 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PHASE_2_L1_CALO_BARREL_TO_CORRELATOR -#define PHASE_2_L1_CALO_BARREL_TO_CORRELATOR - -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" - -#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" - -/* - * Returns the difference in the azimuth coordinates of phi1 and phi2 (all in degrees not radians), taking the wrap-around at 180 degrees into account - */ -inline float p2eg::deltaPhiInDegrees(float phi1, float phi2, const float c = 180) { - float r = std::fmod(phi1 - phi2, 2.0 * c); - if (r < -c) { - r += 2.0 * c; - } else if (r > c) { - r -= 2.0 * c; - } - return r; -} - -/* - * For a given phi in degrees (e.g. computed from some difference), return the phi (in degrees) which takes the wrap-around at 180 degrees into account - */ -inline float p2eg::wrappedPhiInDegrees(float phi) { return p2eg::deltaPhiInDegrees(phi, 0); } - -#endif diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 9400a26b040af..47494cc2a1b76 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -53,7 +53,6 @@ namespace p2eg { static constexpr int CRYSTAL_IN_PHI = 20; // number of crystals in phi, in one 3x4 region (barrel) static constexpr float ECAL_eta_range = 1.4841; - static constexpr float half_crystal_size = 0.00873; static constexpr float slideIsoPtThreshold = 80; static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21; // passes_iso @@ -88,6 +87,8 @@ namespace p2eg { static constexpr int N_GCTETA = 34; static constexpr int N_GCTPHI = 36; + // Note: this follows old GCT geometry, where each GCT has 8 RCT cards (6 unique) with each RCT having 4 towers in phi + // leading to the offset of 6*4 = 24 towers between two GCT card boundaries // for emulator: "top" of the GCT card in phi is tower idx 20, for GCT card #0: static constexpr int GCTCARD_0_TOWER_IPHI_OFFSET = 20; // same but for GCT cards #1 and 2 (cards wrap around phi = 180 degrees): @@ -98,10 +99,24 @@ namespace p2eg { // Outputs to correlator // Fixed number of EG and PF clusters per RCT card in each output SLR - static const int N_EG_CLUSTERS_PER_RCT_CARD = 4; // each eta side - static const int N_PF_CLUSTERS_PER_RCT_CARD = 6; // each eta side + static const int N_EG_CLUSTERS_PER_RCT_CARD = 4; // each eta side + static const int N_PF_CLUSTERS_PER_RCT_CARD = 6; // each eta side // Height of one SLR region in phi in degrees - static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; // including overlap + static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; // including overlap + + // Returns the difference in the azimuth coordinates of phi1 and phi2 (all in degrees not radians), taking the wrap-around at 180 degrees into account + inline float deltaPhiInDegrees(float phi1, float phi2, const float c = 180) { + float r = std::fmod(phi1 - phi2, 2.0 * c); + if (r < -c) { + r += 2.0 * c; + } else if (r > c) { + r -= 2.0 * c; + } + return r; + } + + // For a given phi in degrees (e.g. computed from some difference), return the phi (in degrees) which takes the wrap-around at 180 degrees into account + inline float wrappedPhiInDegrees(float phi) { return p2eg::deltaPhiInDegrees(phi, 0); } ////////////////////////////////////////////////////////////////////////// // RCT: indexing helper functions @@ -857,13 +872,13 @@ namespace p2eg { // Get real eta const float realEta(int cc) { float size_cell = 2 * ECAL_eta_range / (CRYSTALS_IN_TOWER_ETA * n_towers_Eta); - return crystaliEtaFromCardRegionInfo(cc) * size_cell - ECAL_eta_range + half_crystal_size; + return crystaliEtaFromCardRegionInfo(cc) * size_cell - ECAL_eta_range + (size_cell / 2); } // Get real phi const float realPhi(int cc) { float size_cell = 2 * M_PI / (CRYSTALS_IN_TOWER_PHI * n_towers_Phi); - return crystaliPhiFromCardRegionInfo(cc) * size_cell - M_PI + half_crystal_size; + return crystaliPhiFromCardRegionInfo(cc) * size_cell - M_PI + (size_cell / 2); } // Print info @@ -1163,15 +1178,15 @@ namespace p2eg { */ float realEta(void) const { float size_cell = 2 * ECAL_eta_range / (CRYSTALS_IN_TOWER_ETA * n_towers_Eta); - return globalClusteriEta() * size_cell - ECAL_eta_range + half_crystal_size; + return globalClusteriEta() * size_cell - ECAL_eta_range + (size_cell / 2); } /* - * Get GCT cluster's real eta from global iPhi (0-71*5). + * Get GCT cluster's real phi from global iPhi (0-71*5). */ float realPhi(void) const { float size_cell = 2 * M_PI / (CRYSTALS_IN_TOWER_PHI * n_towers_Phi); - return globalClusteriPhi() * size_cell - M_PI + half_crystal_size; + return globalClusteriPhi() * size_cell - M_PI + (size_cell / 2); } /* @@ -1256,30 +1271,59 @@ namespace p2eg { * unique to each GCT card. */ l1tp2::DigitizedClusterCorrelator createDigitizedClusterCorrelator(const int corrTowPhiOffset) const { - // Sascha eta and phi - //ap_uint<7> abseta = 0 ; - ap_uint<8> abseta = 0 ; - ap_uint<10> spare = 0 ; - if(globalClusteriEta()>85) {abseta = globalClusteriEta() - 85 ; spare = 4 ; } - else { abseta = 85 - globalClusteriEta() ; spare = 0 ; } - - ap_int<8> tmpphi = (((towPhi - corrTowPhiOffset) * CRYSTALS_IN_TOWER_PHI) + crPhi) ; - if( tmpphi < 60) {spare = spare | 3;} - else {tmpphi = tmpphi - 60 ; spare = spare | 1 ;} - ap_int<7> phivscenter = ap_int<7>(tmpphi - 30) ; - //if (et > 100) std::cout<<"createDigitizedClusterCorrelator: "< abseta = 0; + ap_uint<10> spare = 0; + if (globalClusteriEta() > n_towers_cardEta * CRYSTALS_IN_TOWER_ETA) { + abseta = globalClusteriEta() - n_towers_cardEta * CRYSTALS_IN_TOWER_ETA; + spare = 4; + } else { + abseta = n_towers_cardEta * CRYSTALS_IN_TOWER_ETA - globalClusteriEta(); + spare = 0; + } + + //// Use towPhi to determine relative phi when clusters are assigned to corect GCT card + //ap_int<8> tmpphi = (((towPhi - corrTowPhiOffset) * CRYSTALS_IN_TOWER_PHI) + crPhi) ; // range between 0 to 120 + //if (tmpphi < PHI_RANGE_PER_SLR_DEGREES/2) {spare = spare | 3;} + //else { tmpphi = tmpphi - PHI_RANGE_PER_SLR_DEGREES/2 ; spare = spare | 1 ;} // set to range between 0 to 60 + //ap_int<7> phivscenter = ap_int<7>(tmpphi - PHI_RANGE_PER_SLR_DEGREES/4) ; // set to range between -30 to 30 + + // Use realPhi() to determine relative phi as current GCT card assignment uses old geometry + // This is emulator specific to bypass geometry issue + int cardnumber = 0; + float regionCentersInDegrees[6] = {10.0, 70.0, 130.0, -170.0, -110.0, -50.0}; + float clusterRealPhiAsDegree = realPhi() * 180 / M_PI; + ap_int<7> phivscenter = 0; + for (int i = 0; i < 6; i++) { + float tempDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[i]); + if (abs(tempDifference) < PHI_RANGE_PER_SLR_DEGREES / 4) { + phivscenter = 0x7F & int(std::floor(tempDifference)); // greatest integer <= x + cardnumber = int(i / 2); + } + } + + float cardCentersInDegrees[3] = {40., 160., -80.}; + if (p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, cardCentersInDegrees[cardnumber]) > 0) { + spare = spare | 3; + } else { + spare = spare | 1; + } + + ap_uint<6> shape = (0x3F * et2x5 / et5x5); // normalize to 0x3F + ap_uint<3> quality = + (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); + return l1tp2::DigitizedClusterCorrelator( et, // technically we are just multiplying and then dividing again by the LSB abseta, phivscenter, - ap_uint<6>(0x3F) , - ap_uint<6>(0x3F) , - ap_uint<6>(0x3F) , - ap_uint<3>(0x7) , + ap_uint<6>(hoe & 0x3F), + ap_uint<6>(iso & 0x3F), + ap_uint<6>(shape), + ap_uint<3>(quality), ap_uint<5>(timing), ap_uint<2>(brems), - ap_uint<10>(spare) , - nGCTCard, true ) ; + ap_uint<10>(spare), + cardnumber); } /* @@ -1327,7 +1371,9 @@ namespace p2eg { inline float totalEtFloat() const { return ((float)et * ECAL_LSB); } // Return total energy as a float (assuming the energy uses the ECAL LSB convention) + inline float ecalEtFloat() const { return ((float)ecalEt * ECAL_LSB); } // Return ECAL energy as a float + inline float hcalEtFloat() const { return ((float)hcalEt * HCAL_LSB); } // Return HCAL energy as a float, use HCAL LSB @@ -1342,6 +1388,38 @@ namespace p2eg { hcalEt = rctTower.hcalEt; } + void addHoverEToTower(ap_uint<12> ECAL, ap_uint<12> HCAL) { + ap_uint<4> hoeOut = 0; + ap_uint<1> hoeLSB = 0; + ap_uint<12> A; + ap_uint<12> B; + + A = (ECAL > HCAL) ? ECAL : HCAL; + B = (ECAL > HCAL) ? HCAL : ECAL; + + if (ECAL == 0 || HCAL == 0 || HCAL >= ECAL) + hoeLSB = 0; + else + hoeLSB = 1; + if (A > B) { + if (A > 2 * B) + hoeOut = 0x1; + if (A > 4 * B) + hoeOut = 0x2; + if (A > 8 * B) + hoeOut = 0x3; + if (A > 16 * B) + hoeOut = 0x4; + if (A > 32 * B) + hoeOut = 0x5; + if (A > 64 * B) + hoeOut = 0x6; + if (A > 128 * B) + hoeOut = 0x7; + } + hoe = hoeLSB | (hoeOut << 1); + } + /* * Correlator fiber convention -> Global GCT convention * Get tower's global (iEta) from the GCTCorrFiber index [0, 64) and the tower's postion in the fiber [0, 17). @@ -1419,8 +1497,8 @@ namespace p2eg { */ l1tp2::CaloTower createCaloTowerFromFiberIdx(int nGCTCard, int iFiber, int iTowerInFiber) { l1tp2::CaloTower l1CaloTower; - l1CaloTower.setEcalTowerEt(ecalEtFloat()); // float: ECAL divide by 8.0 - l1CaloTower.setHcalTowerEt(hcalEtFloat()); // float: HCAL multiply by LSB + l1CaloTower.setEcalTowerEt(ecalEtFloat()); + l1CaloTower.setHcalTowerEt(hcalEtFloat()); int global_tower_iEta = globalToweriEta(nGCTCard, iFiber, iTowerInFiber); int global_tower_iPhi = globalToweriPhi(nGCTCard, iFiber, iTowerInFiber); l1CaloTower.setTowerIEta(global_tower_iEta); @@ -1435,9 +1513,8 @@ namespace p2eg { */ l1tp2::CaloTower createFullTowerFromCardIdx(int nGCTCard, int gctCard_tower_iEta, int gctCard_tower_iPhi) { l1tp2::CaloTower l1CaloTower; - // Store total Et (HCAL+ECAL) in the ECAL Et member - l1CaloTower.setEcalTowerEt(totalEtFloat()); - l1CaloTower.setHcalTowerEt(ecalEtFloat()); + l1CaloTower.setEcalTowerEt(ecalEtFloat()); + l1CaloTower.setHcalTowerEt(hcalEtFloat()); int global_tower_iEta = globalToweriEtaFromGCTcardiEta(gctCard_tower_iEta); int global_tower_iPhi = globalToweriPhiFromGCTcardiPhi(nGCTCard, gctCard_tower_iPhi); l1CaloTower.setTowerIEta(global_tower_iEta); @@ -1680,12 +1757,6 @@ namespace p2eg { int corrFiberIndexOffset, int corrTowPhiOffset); - /*******************************************************************************************/ - /* Interface to correlator helper functions (defined in Phase2L1CaloBarrelToCorrelator.h) */ - /*******************************************************************************************/ - float deltaPhiInDegrees(float phi1, float phi2, const float c); - float wrappedPhiInDegrees(float phi); - /* * Generic function to compare hadronic (had) or EM digi clusters. */ diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h index 2fedbafe06d7c..da08b712c87ea 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h @@ -31,20 +31,15 @@ namespace gctpf { typedef struct { float et; + float ecal; int eta; int phi; - } GCTpfcluster_t; + } GCTint_t; typedef struct { - GCTpfcluster_t GCTpfclusters[nPFClusterSLR]; + GCTint_t GCTpfclusters[nPFClusterSLR]; } PFcluster_t; - typedef struct { - float et; - int eta; - int phi; - } GCTint_t; - typedef struct { GCTint_t t[nTowerPhiSLR]; } GCTEtaStrip_t; @@ -173,12 +168,13 @@ namespace gctpf { return max; } - inline Region_t initStructure(float temp[nTowerEtaSLR][nTowerPhiSLR]) { + inline Region_t initStructure(std::pair temp[nTowerEtaSLR][nTowerPhiSLR]) { Region_t r; for (int i = 0; i < nTowerPhiSLR; i++) { for (int j = 0; j < nTowerEtaSLR; j++) { - r.s[j].t[i].et = temp[j][i]; + r.s[j].t[i].et = temp[j][i].first; + r.s[j].t[i].ecal = temp[j][i].second; r.s[j].t[i].eta = j; r.s[j].t[i].phi = i; } @@ -193,6 +189,7 @@ namespace gctpf { for (int i = 0; i < nHfPhi / 6; i++) { for (int j = 0; j < nHfEta; j++) { r.s[j].t[i].et = temp[j][i]; + r.s[j].t[i].ecal = 0.; r.s[j].t[i].eta = j; r.s[j].t[i].phi = i; } @@ -201,20 +198,23 @@ namespace gctpf { return r; } - inline float getEt(float temp[nTowerEtaSLR][nTowerPhiSLR], int eta, int phi) { + inline std::pair getEt(std::pair temp[nTowerEtaSLR][nTowerPhiSLR], int eta, int phi) { float et_sumEta[3] = {0., 0., 0.}; + float ecal_sumEta[3] = {0., 0., 0.}; for (int i = 0; i < (nTowerEtaSLR - 2); i++) { for (int j = 0; j < (nTowerPhiSLR - 2); j++) { if (i + 1 == eta && j + 1 == phi) { for (int k = 0; k < 3; k++) { - et_sumEta[k] = temp[i + k][j] + temp[i + k][j + 1] + temp[i + k][j + 2]; + et_sumEta[k] = temp[i + k][j].first + temp[i + k][j + 1].first + temp[i + k][j + 2].first; + ecal_sumEta[k] = temp[i + k][j].second + temp[i + k][j + 1].second + temp[i + k][j + 2].second; } } } } - float pfcluster_et = et_sumEta[0] + et_sumEta[1] + et_sumEta[2]; + std::pair pfcluster_et = + std::make_pair(et_sumEta[0] + et_sumEta[1] + et_sumEta[2], ecal_sumEta[0] + ecal_sumEta[1] + ecal_sumEta[2]); return pfcluster_et; } @@ -250,12 +250,12 @@ namespace gctpf { return pfcluster_et; } - inline void RemoveTmp(float temp[nTowerEtaSLR][nTowerPhiSLR], int eta, int phi) { + inline void RemoveTmp(std::pair temp[nTowerEtaSLR][nTowerPhiSLR], int eta, int phi) { for (int i = 0; i < nTowerEtaSLR; i++) { if (i + 1 >= eta && i <= eta + 1) { for (int j = 0; j < nTowerPhiSLR; j++) { if (j + 1 >= phi && j <= phi + 1) { - temp[i][j] = 0; + temp[i][j] = std::make_pair(0., 0.); } } } @@ -278,8 +278,10 @@ namespace gctpf { return; } - inline GCTpfcluster_t recoPfcluster(float temporary[nTowerEtaSLR][nTowerPhiSLR], int etaoffset, int phioffset) { - GCTpfcluster_t pfclusterReturn; + inline GCTint_t recoPfcluster(std::pair temporary[nTowerEtaSLR][nTowerPhiSLR], + int etaoffset, + int phioffset) { + GCTint_t pfclusterReturn; Region_t region; @@ -287,7 +289,7 @@ namespace gctpf { GCTint_t regionMax = getPeakPosition(region); - float pfcluster_et = getEt(temporary, regionMax.eta, regionMax.phi); + std::pair pfcluster_et = getEt(temporary, regionMax.eta, regionMax.phi); float pfcluster_eta = regionMax.eta - 2 + etaoffset; float pfcluster_phi = regionMax.phi - 2 + phioffset; @@ -295,20 +297,22 @@ namespace gctpf { if (!(regionMax.eta >= 2 && regionMax.eta < (nTowerEtaSLR - 2) && regionMax.phi >= 2 && regionMax.phi < (nTowerPhiSLR - 2))) { - pfcluster_et = 0; // set energy to be zero if maximum energy tower is not within the unique region - pfcluster_eta = 2; // choose the default to be at one corner of the unique region - pfcluster_phi = 2; // choose the default to be at one corner of the unique region + pfcluster_et = + std::make_pair(0., 0.); // set energy to be zero if maximum energy tower is not within the unique region + pfcluster_eta = 2; // choose the default to be at one corner of the unique region + pfcluster_phi = 2; // choose the default to be at one corner of the unique region } - pfclusterReturn.et = pfcluster_et; + pfclusterReturn.et = pfcluster_et.first; + pfclusterReturn.ecal = pfcluster_et.second; pfclusterReturn.eta = pfcluster_eta; pfclusterReturn.phi = pfcluster_phi; return pfclusterReturn; } - inline GCTpfcluster_t recoPfclusterHF(float temporary[nHfEta][nHfPhi / 6], int etaoffset, int phioffset) { - GCTpfcluster_t pfclusterReturn; + inline GCTint_t recoPfclusterHF(float temporary[nHfEta][nHfPhi / 6], int etaoffset, int phioffset) { + GCTint_t pfclusterReturn; RegionHF_t region; @@ -321,6 +325,7 @@ namespace gctpf { RemoveTmpHF(temporary, regionMax.eta, regionMax.phi); pfclusterReturn.et = pfcluster_et; + pfclusterReturn.ecal = 0.; pfclusterReturn.eta = regionMax.eta + etaoffset; pfclusterReturn.phi = regionMax.phi + phioffset; if (pfclusterReturn.phi < 0) @@ -329,8 +334,10 @@ namespace gctpf { return pfclusterReturn; } - inline PFcluster_t pfcluster(float temporary[nTowerEtaSLR][nTowerPhiSLR], int etaoffset, int phioffset) { - GCTpfcluster_t pfcluster[nPFClusterSLR]; + inline PFcluster_t pfcluster(std::pair temporary[nTowerEtaSLR][nTowerPhiSLR], + int etaoffset, + int phioffset) { + GCTint_t pfcluster[nPFClusterSLR]; for (int i = 0; i < nPFClusterSLR; i++) { pfcluster[i] = recoPfcluster(temporary, etaoffset, phioffset); @@ -340,6 +347,7 @@ namespace gctpf { for (int i = 0; i < nPFClusterSLR; i++) { GCTPfclusters.GCTpfclusters[i].et = pfcluster[i].et; + GCTPfclusters.GCTpfclusters[i].ecal = pfcluster[i].ecal; GCTPfclusters.GCTpfclusters[i].eta = pfcluster[i].eta; GCTPfclusters.GCTpfclusters[i].phi = pfcluster[i].phi; } @@ -348,7 +356,7 @@ namespace gctpf { } inline PFcluster_t pfclusterHF(float temporary[nHfEta][nHfPhi / 6], int etaoffset, int phioffset) { - GCTpfcluster_t pfcluster[nPFClusterSLR]; + GCTint_t pfcluster[nPFClusterSLR]; for (int i = 0; i < nPFClusterSLR; i++) { pfcluster[i] = recoPfclusterHF(temporary, etaoffset, phioffset); diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h index 3ca1f98e2f1ae..f6806bdb8192d 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h @@ -1,12 +1,10 @@ #ifndef Phase2L1CaloToCorrelatorTMI18_H #define Phase2L1CaloToCorrelatorTMI18_H - // system include files #include #include - #include #include #include @@ -36,17 +34,10 @@ #include #include "FWCore/Framework/interface/ESHandle.h" -//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" -//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" -#ifdef __MAKECINT__ -// #pragma extra_include "TLorentzVector.h"; -#pragma link C++ class std::vector; -#endif - // // class declaration // diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h index 3f2b02aa49d44..6c5ed035dcb44 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h @@ -240,7 +240,6 @@ inline p2eg::GCTintTowers_t p2eg::getFullTowers(const p2eg::GCTinternal_t& GCTin ap_uint<15> phi = i + i1; ap_uint<15> eta = p2eg::N_GCTETA / 2 + k; GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].et; - GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hoe; GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].ecalEt; GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hcalEt; for (int ic1 = 0; ic1 < 4; ic1++) { @@ -250,9 +249,13 @@ inline p2eg::GCTintTowers_t p2eg::getFullTowers(const p2eg::GCTinternal_t& GCTin if (eta == eta1 && phi == phi1) { GCTintTowers.GCTtower[eta][phi].et = (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); + GCTintTowers.GCTtower[eta][phi].ecalEt = + (GCTintTowers.GCTtower[eta][phi].ecalEt + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); } } } + GCTintTowers.GCTtower[eta][phi].addHoverEToTower(GCTintTowers.GCTtower[eta][phi].ecalEt, + GCTintTowers.GCTtower[eta][phi].hcalEt); } } } @@ -264,7 +267,6 @@ inline p2eg::GCTintTowers_t p2eg::getFullTowers(const p2eg::GCTinternal_t& GCTin ap_uint<15> eta = p2eg::N_GCTETA / 2 - k - 1; ap_uint<15> phi = i + i1 - p2eg::N_GCTPOSITIVE_FIBERS; GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].et; - GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hoe; GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].ecalEt; GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hcalEt; for (int ic1 = 0; ic1 < 4; ic1++) { @@ -274,9 +276,13 @@ inline p2eg::GCTintTowers_t p2eg::getFullTowers(const p2eg::GCTinternal_t& GCTin if (eta == eta1 && phi == phi1) { GCTintTowers.GCTtower[eta][phi].et = (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); + GCTintTowers.GCTtower[eta][phi].ecalEt = + (GCTintTowers.GCTtower[eta][phi].ecalEt + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); } } } + GCTintTowers.GCTtower[eta][phi].addHoverEToTower(GCTintTowers.GCTtower[eta][phi].ecalEt, + GCTintTowers.GCTtower[eta][phi].hcalEt); } } } diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc index b5172f5ac6459..d55b8faf2485a 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc @@ -237,8 +237,8 @@ void Phase2L1CaloJetEmulator::produce(edm::Event& iEvent, const edm::EventSetup& for (const l1tp2::CaloTower& i : *caloTowerCollection) { int ieta = i.towerIEta(); int iphi = i.towerIPhi(); - if (i.ecalTowerEt() > 1.) - GCTintTowers[ieta][iphi] = i.ecalTowerEt(); // suppress <= 1 GeV towers + if (i.ecalTowerEt() > 1. || i.hcalTowerEt() > 1.) + GCTintTowers[ieta][iphi] = i.ecalTowerEt() + i.hcalTowerEt(); // suppress <= 1 GeV towers else GCTintTowers[ieta][iphi] = 0; realEta[ieta][iphi] = i.towerEta(); diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc index 935e9ed1cd387..8d834d38c7d1b 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc @@ -91,22 +91,24 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event cms::Exception("Phase2L1CaloPFClusterEmulator") << "Failed to get towers from caloTowerCollection!"; float GCTintTowers[nTowerEta][nTowerPhi]; + float GCTintTowersEcal[nTowerEta][nTowerPhi]; float realEta[nTowerEta][nTowerPhi]; float realPhi[nTowerEta][nTowerPhi]; for (const l1tp2::CaloTower& i : *caloTowerCollection) { int ieta = i.towerIEta(); int iphi = i.towerIPhi(); - GCTintTowers[ieta][iphi] = i.ecalTowerEt(); + GCTintTowers[ieta][iphi] = i.ecalTowerEt() + i.hcalTowerEt(); + GCTintTowersEcal[ieta][iphi] = i.ecalTowerEt(); realEta[ieta][iphi] = i.towerEta(); realPhi[ieta][iphi] = i.towerPhi(); } - float regions[nSLR][nTowerEtaSLR][nTowerPhiSLR]; + std::pair regions[nSLR][nTowerEtaSLR][nTowerPhiSLR]; for (int ieta = 0; ieta < nTowerEtaSLR; ieta++) { for (int iphi = 0; iphi < nTowerPhiSLR; iphi++) { for (int k = 0; k < nSLR; k++) { - regions[k][ieta][iphi] = 0.; + regions[k][ieta][iphi] = std::make_pair(0., 0.); } } } @@ -117,26 +119,32 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event for (int iphi = 0; iphi < nTowerPhiSLR; iphi++) { if (ieta > 1) { if (iphi > 1) - regions[0][ieta][iphi] = GCTintTowers[ieta - 2][iphi - 2]; + regions[0][ieta][iphi] = + std::make_pair(GCTintTowers[ieta - 2][iphi - 2], GCTintTowersEcal[ieta - 2][iphi - 2]); for (int k = 1; k < 17; k++) { - regions[k * 2][ieta][iphi] = GCTintTowers[ieta - 2][iphi + k * 4 - 2]; + regions[k * 2][ieta][iphi] = + std::make_pair(GCTintTowers[ieta - 2][iphi + k * 4 - 2], GCTintTowersEcal[ieta - 2][iphi + k * 4 - 2]); } if (iphi < 6) - regions[34][ieta][iphi] = GCTintTowers[ieta - 2][iphi + 66]; + regions[34][ieta][iphi] = + std::make_pair(GCTintTowers[ieta - 2][iphi + 66], GCTintTowersEcal[ieta - 2][iphi + 66]); } if (ieta < 19) { if (iphi > 1) - regions[1][ieta][iphi] = GCTintTowers[ieta + 15][iphi - 2]; + regions[1][ieta][iphi] = + std::make_pair(GCTintTowers[ieta + 15][iphi - 2], GCTintTowersEcal[ieta + 15][iphi - 2]); for (int k = 1; k < 17; k++) { - regions[k * 2 + 1][ieta][iphi] = GCTintTowers[ieta + 15][iphi + k * 4 - 2]; + regions[k * 2 + 1][ieta][iphi] = + std::make_pair(GCTintTowers[ieta + 15][iphi + k * 4 - 2], GCTintTowersEcal[ieta + 15][iphi + k * 4 - 2]); } if (iphi < 6) - regions[35][ieta][iphi] = GCTintTowers[ieta + 15][iphi + 66]; + regions[35][ieta][iphi] = + std::make_pair(GCTintTowers[ieta + 15][iphi + 66], GCTintTowersEcal[ieta + 15][iphi + 66]); } } } - float temporary[nTowerEtaSLR][nTowerPhiSLR]; + std::pair temporary[nTowerEtaSLR][nTowerPhiSLR]; int etaoffset = 0; int phioffset = 0; @@ -164,6 +172,7 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event float towerphi = realPhi[gcteta][gctphi]; l1tp2::CaloPFCluster l1CaloPFCluster; l1CaloPFCluster.setClusterEt(tempPfclusters.GCTpfclusters[i].et); + l1CaloPFCluster.setEcalEt(tempPfclusters.GCTpfclusters[i].ecal); l1CaloPFCluster.setClusterIEta(gcteta); l1CaloPFCluster.setClusterIPhi(gctphi); l1CaloPFCluster.setClusterEta(towereta); @@ -298,6 +307,7 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event float towerphi = hfPhi[hfeta][hfphi]; l1tp2::CaloPFCluster l1CaloPFCluster; l1CaloPFCluster.setClusterEt(tempPfclustersHF.GCTpfclusters[i].et); + l1CaloPFCluster.setEcalEt(0.); l1CaloPFCluster.setClusterIEta(hfeta); l1CaloPFCluster.setClusterIPhi(hfphi); l1CaloPFCluster.setClusterEta(towereta); diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc index dd4e28d1159b8..833aa9b57c246 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc @@ -5,15 +5,10 @@ #include #include #include -// #include #include #include #include #include -#include -#ifdef __MAKECINT__ -#pragma link C++ class vector+; -#endif // user include files #include "FWCore/Framework/interface/stream/EDProducer.h" @@ -26,13 +21,10 @@ #include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h" -//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelatorTMI18.h" -//#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedPFClusterCorrelatorTMI18.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" - class Phase2L1CaloToCorrelatorTMI18 : public edm::stream::EDProducer<> { public: explicit Phase2L1CaloToCorrelatorTMI18(const edm::ParameterSet&); @@ -46,38 +38,49 @@ class Phase2L1CaloToCorrelatorTMI18 : public edm::stream::EDProducer<> { edm::EDGetTokenT gctHadDigiClustersSrc_; }; - -Phase2L1CaloToCorrelatorTMI18::Phase2L1CaloToCorrelatorTMI18( const edm::ParameterSet & cfg ) : - gctEmDigiClustersSrc_(consumes(cfg.getParameter("gctEmDigiClusters"))), - gctHadDigiClustersSrc_(consumes(cfg.getParameter("gctHadDigiClusters"))) -{ +Phase2L1CaloToCorrelatorTMI18::Phase2L1CaloToCorrelatorTMI18(const edm::ParameterSet& cfg) + : gctEmDigiClustersSrc_( + consumes(cfg.getParameter("gctEmDigiClusters"))), + gctHadDigiClustersSrc_( + consumes(cfg.getParameter("gctHadDigiClusters"))) { produces("DigitizedCaloToCorrelatorTMI18"); } -void Phase2L1CaloToCorrelatorTMI18::produce( edm::Event& evt, const edm::EventSetup& es ) - { +void Phase2L1CaloToCorrelatorTMI18::produce(edm::Event& evt, const edm::EventSetup& es) { using namespace edm; - std::unique_ptr caloCandsTMI18(std::make_unique()); - - int cntr03pos = 0 ; - int cntr03neg = 0 ; - int cntr01pos = 0 ; - int cntr01neg = 0 ; - - int cntr13pos = 0 ; - int cntr13neg = 0 ; - int cntr11pos = 0 ; - int cntr11neg = 0 ; - - int cntr23pos = 0 ; - int cntr23neg = 0 ; - int cntr21pos = 0 ; - int cntr21neg = 0 ; - - ap_uint<64> mydata = 0 ; - ap_uint<64> dataToCL1Card0[162] = {0} ; - ap_uint<64> dataToCL1Card1[162] = {0} ; - ap_uint<64> dataToCL1Card2[162] = {0} ; + std::unique_ptr caloCandsTMI18( + std::make_unique()); + + int EM_SLR1_POS_OFFSET = 1; + int EM_SLR1_NEG_OFFSET = 17; + int PF_SLR1_POS_OFFSET = 33; + int PF_SLR1_NEG_OFFSET = 57; + int EM_SLR3_POS_OFFSET = 82; + int EM_SLR3_NEG_OFFSET = 98; + int PF_SLR3_POS_OFFSET = 114; + int PF_SLR3_NEG_OFFSET = 138; + int NUM_EM_WORDS = 16; + int NUM_PF_WORDS = 24; + + int cntr03pos = 0; + int cntr03neg = 0; + int cntr01pos = 0; + int cntr01neg = 0; + + int cntr13pos = 0; + int cntr13neg = 0; + int cntr11pos = 0; + int cntr11neg = 0; + + int cntr23pos = 0; + int cntr23neg = 0; + int cntr21pos = 0; + int cntr21neg = 0; + + ap_uint<64> mydata = 0; + ap_uint<64> dataToCL1Card0[162] = {0}; + ap_uint<64> dataToCL1Card1[162] = {0}; + ap_uint<64> dataToCL1Card2[162] = {0}; l1tp2::GCTDigiClusterLink clusterCollCard0(162); l1tp2::GCTDigiClusterLink clusterCollCard1(162); l1tp2::GCTDigiClusterLink clusterCollCard2(162); @@ -85,259 +88,204 @@ void Phase2L1CaloToCorrelatorTMI18::produce( edm::Event& evt, const edm::EventSe // SLR1 and SLR3 both send 24 PFclusters each from +ve and -ve eta, total 48 words: 4x12(x64b) edm::Handle gctHadDigiClusters; - if(evt.getByToken(gctHadDigiClustersSrc_, gctHadDigiClusters)) { + if (evt.getByToken(gctHadDigiClustersSrc_, gctHadDigiClusters)) { for (int iLink = 0; iLink < 12; iLink++) { // in order: // GCT1 SLR3 +ve, GCT1 SLR3 -ve, GCT1 SLR1 +ve, GCT1 SLR1 -ve // GCT2 SLR3 +ve, GCT2 SLR3 -ve, GCT2 SLR1 +ve, GCT2 SLR1 -ve // GCT3 SLR3 +ve, GCT3 SLR3 -ve, GCT3 SLR1 +ve, GCT3 SLR1 -ve - int iGCT = (iLink/4); + int iGCT = (iLink / 4); // 4 RCT regions per GCT - int iRCT = iLink - iGCT*4; + int iRCT = iLink - iGCT * 4; // Eta: positive or negative depends on the link. If iLink is even, it is in positive eta bool isNegativeEta = (iRCT % 2 == 1); // SLR alternates every two links bool isSLR3 = ((iLink % 4) < 2); bool isSLR1 = !isSLR3; - for (const auto & cluster : (*gctHadDigiClusters).at(iLink)) { - mydata = cluster.data() ; - if (isSLR1 && isNegativeEta) goto slr1negp; - if (isSLR1 && !isNegativeEta) goto slr1posp; - if (isSLR3 && isNegativeEta) goto slr3negp; - if (isSLR3 && !isNegativeEta) goto slr3posp; - -slr3posp: ; - - if(iGCT == 0 && cntr03pos < 24){ - dataToCL1Card0[17+cntr03pos] = mydata; - clusterCollCard0[17+cntr03pos] = cluster; - cntr03pos++; - goto fillendp; - } - if(iGCT == 1 && cntr13pos < 24){ - dataToCL1Card1[17+cntr13pos] = mydata; - clusterCollCard1[17+cntr13pos] = cluster; - cntr13pos++; - goto fillendp; - } - if(iGCT == 2 && cntr23pos < 24){ - dataToCL1Card2[17+cntr23pos] = mydata; - clusterCollCard2[17+cntr23pos] = cluster; - cntr23pos++; - goto fillendp; - } - goto fillendp; - -slr3negp: ; + for (const auto& cluster : (*gctHadDigiClusters).at(iLink)) { + mydata = cluster.data(); - if(iGCT == 0 && cntr03neg < 24){ - dataToCL1Card0[57+cntr03neg] = mydata; - clusterCollCard0[57+cntr03neg] = cluster; - cntr03neg++; - goto fillendp; - } - if(iGCT == 1 && cntr13neg < 24){ - dataToCL1Card1[57+cntr13neg] = mydata; - clusterCollCard1[57+cntr13neg] = cluster; - cntr13neg++; - goto fillendp; - } - if(iGCT == 2 && cntr23neg < 24){ - dataToCL1Card2[57+cntr23neg] = mydata; - clusterCollCard2[57+cntr23neg] = cluster; - cntr23neg++; - goto fillendp; - } - goto fillendp; - -slr1posp: ; - - if(iGCT == 0 && cntr01pos < 24){ - dataToCL1Card0[81+17+cntr01pos] = mydata; - clusterCollCard0[81+17+cntr01pos] = cluster; + if ((iGCT == 0) && isSLR1 && !isNegativeEta && (cntr01pos < NUM_PF_WORDS)) { + dataToCL1Card0[PF_SLR1_POS_OFFSET + cntr01pos] = mydata; + clusterCollCard0[PF_SLR1_POS_OFFSET + cntr01pos] = cluster; cntr01pos++; - goto fillendp; - } - if(iGCT == 1 && cntr11pos < 24){ - dataToCL1Card1[81+17+cntr11pos] = mydata; - clusterCollCard1[81+17+cntr11pos] = cluster; + } + if ((iGCT == 1) && isSLR1 && !isNegativeEta && (cntr11pos < NUM_PF_WORDS)) { + dataToCL1Card1[PF_SLR1_POS_OFFSET + cntr11pos] = mydata; + clusterCollCard1[PF_SLR1_POS_OFFSET + cntr11pos] = cluster; cntr11pos++; - goto fillendp; - } - if(iGCT == 2 && cntr21pos < 24){ - dataToCL1Card2[81+17+cntr21pos] = mydata; - clusterCollCard2[81+17+cntr21pos] = cluster; + } + if ((iGCT == 2) && isSLR1 && !isNegativeEta && (cntr21pos < NUM_PF_WORDS)) { + dataToCL1Card2[PF_SLR1_POS_OFFSET + cntr21pos] = mydata; + clusterCollCard2[PF_SLR1_POS_OFFSET + cntr21pos] = cluster; cntr21pos++; - goto fillendp; - } - goto fillendp; - -slr1negp: ; - - if(iGCT == 0 && cntr01neg < 24){ - dataToCL1Card0[81+57+cntr01neg] = mydata; - clusterCollCard0[81+57+cntr01neg] = cluster; + } + if ((iGCT == 0) && isSLR1 && isNegativeEta && (cntr01neg < NUM_PF_WORDS)) { + dataToCL1Card0[PF_SLR1_NEG_OFFSET + cntr01neg] = mydata; + clusterCollCard0[PF_SLR1_NEG_OFFSET + cntr01neg] = cluster; cntr01neg++; - goto fillendp; - } - if(iGCT == 1 && cntr11neg < 24){ - dataToCL1Card1[81+57+cntr11neg] = mydata; - clusterCollCard1[81+57+cntr11neg] = cluster; + } + if ((iGCT == 1) && isSLR1 && isNegativeEta && (cntr11neg < NUM_PF_WORDS)) { + dataToCL1Card1[PF_SLR1_NEG_OFFSET + cntr11neg] = mydata; + clusterCollCard1[PF_SLR1_NEG_OFFSET + cntr11neg] = cluster; cntr11neg++; - goto fillendp; - } - if(iGCT == 2 && cntr21neg < 24){ - dataToCL1Card2[81+57+cntr21neg] = mydata; - clusterCollCard2[81+57+cntr21neg] = cluster; + } + if ((iGCT == 2) && isSLR1 && isNegativeEta && (cntr21neg < NUM_PF_WORDS)) { + dataToCL1Card2[PF_SLR1_NEG_OFFSET + cntr21neg] = mydata; + clusterCollCard2[PF_SLR1_NEG_OFFSET + cntr21neg] = cluster; cntr21neg++; - goto fillendp; - } - -fillendp: ; + } + if ((iGCT == 0) && isSLR3 && !isNegativeEta && (cntr03pos < NUM_PF_WORDS)) { + dataToCL1Card0[PF_SLR3_POS_OFFSET + cntr03pos] = mydata; + clusterCollCard0[PF_SLR3_POS_OFFSET + cntr03pos] = cluster; + cntr03pos++; + } + if ((iGCT == 1) && isSLR3 && !isNegativeEta && (cntr13pos < NUM_PF_WORDS)) { + dataToCL1Card1[PF_SLR3_POS_OFFSET + cntr13pos] = mydata; + clusterCollCard1[PF_SLR3_POS_OFFSET + cntr13pos] = cluster; + cntr13pos++; + } + if ((iGCT == 2) && isSLR3 && !isNegativeEta && (cntr23pos < NUM_PF_WORDS)) { + dataToCL1Card2[PF_SLR3_POS_OFFSET + cntr23pos] = mydata; + clusterCollCard2[PF_SLR3_POS_OFFSET + cntr23pos] = cluster; + cntr23pos++; + } + if ((iGCT == 0) && isSLR3 && isNegativeEta && (cntr03neg < NUM_PF_WORDS)) { + dataToCL1Card0[PF_SLR3_NEG_OFFSET + cntr03neg] = mydata; + clusterCollCard0[PF_SLR3_NEG_OFFSET + cntr03neg] = cluster; + cntr03neg++; + } + if ((iGCT == 1) && isSLR3 && isNegativeEta && (cntr13neg < NUM_PF_WORDS)) { + dataToCL1Card1[PF_SLR3_NEG_OFFSET + cntr13neg] = mydata; + clusterCollCard1[PF_SLR3_NEG_OFFSET + cntr13neg] = cluster; + cntr13neg++; + } + if ((iGCT == 2) && isSLR3 && isNegativeEta && (cntr23neg < NUM_PF_WORDS)) { + dataToCL1Card2[PF_SLR3_NEG_OFFSET + cntr23neg] = mydata; + clusterCollCard2[PF_SLR3_NEG_OFFSET + cntr23neg] = cluster; + cntr23neg++; + } } } } - cntr03pos = 0 ; - cntr03neg = 0 ; - cntr01pos = 0 ; - cntr01neg = 0 ; + cntr03pos = 0; + cntr03neg = 0; + cntr01pos = 0; + cntr01neg = 0; - cntr13pos = 0 ; - cntr13neg = 0 ; - cntr11pos = 0 ; - cntr11neg = 0 ; + cntr13pos = 0; + cntr13neg = 0; + cntr11pos = 0; + cntr11neg = 0; - cntr23pos = 0 ; - cntr23neg = 0 ; - cntr21pos = 0 ; - cntr21neg = 0 ; + cntr23pos = 0; + cntr23neg = 0; + cntr21pos = 0; + cntr21neg = 0; edm::Handle gctEmDigiClusters; - if(evt.getByToken(gctEmDigiClustersSrc_, gctEmDigiClusters)){ + if (evt.getByToken(gctEmDigiClustersSrc_, gctEmDigiClusters)) { for (int iLink = 0; iLink < 12; iLink++) { // in order: // GCT1 SLR3 +ve, GCT1 SLR3 -ve, GCT1 SLR1 +ve, GCT1 SLR1 -ve // GCT2 SLR3 +ve, GCT2 SLR3 -ve, GCT2 SLR1 +ve, GCT2 SLR1 -ve // GCT3 SLR3 +ve, GCT3 SLR3 -ve, GCT3 SLR1 +ve, GCT3 SLR1 -ve - int iGCT = (iLink/4); + int iGCT = (iLink / 4); // 4 RCT regions per GCT - int iRCT = iLink - iGCT*4; + int iRCT = iLink - iGCT * 4; // Eta: positive or negative depends on the link. If iLink is even, it is in positive eta bool isNegativeEta = (iRCT % 2 == 1); // SLR alternates every two links bool isSLR3 = ((iLink % 4) < 2); bool isSLR1 = !isSLR3; - for (const auto & cluster : (*gctEmDigiClusters).at(iLink)) { - mydata = cluster.data() ; - if (isSLR1 && isNegativeEta) goto slr1neg; - if (isSLR1 && !isNegativeEta) goto slr1pos; - if (isSLR3 && isNegativeEta) goto slr3neg; - if (isSLR3 && !isNegativeEta) goto slr3pos; - -slr3pos: ; + for (const auto& cluster : (*gctEmDigiClusters).at(iLink)) { + mydata = cluster.data(); - if(iGCT == 0 && cntr03pos < 16){ - dataToCL1Card0[1+cntr03pos] = mydata; - clusterCollCard0[1+cntr03pos] = cluster; + if ((iGCT == 0) && isSLR1 && !isNegativeEta && (cntr01pos < NUM_EM_WORDS)) { + dataToCL1Card0[EM_SLR1_POS_OFFSET + cntr01pos] = mydata; + clusterCollCard0[EM_SLR1_POS_OFFSET + cntr01pos] = cluster; + cntr01pos++; + } + if ((iGCT == 1) && isSLR1 && !isNegativeEta && (cntr11pos < NUM_EM_WORDS)) { + dataToCL1Card1[EM_SLR1_POS_OFFSET + cntr11pos] = mydata; + clusterCollCard1[EM_SLR1_POS_OFFSET + cntr11pos] = cluster; + cntr11pos++; + } + if ((iGCT == 2) && isSLR1 && !isNegativeEta && (cntr21pos < NUM_EM_WORDS)) { + dataToCL1Card2[EM_SLR1_POS_OFFSET + cntr21pos] = mydata; + clusterCollCard2[EM_SLR1_POS_OFFSET + cntr21pos] = cluster; + cntr21pos++; + } + if ((iGCT == 0) && isSLR1 && isNegativeEta && (cntr01neg < NUM_EM_WORDS)) { + dataToCL1Card0[EM_SLR1_NEG_OFFSET + cntr01neg] = mydata; + clusterCollCard0[EM_SLR1_NEG_OFFSET + cntr01neg] = cluster; + cntr01neg++; + } + if ((iGCT == 1) && isSLR1 && isNegativeEta && (cntr11neg < NUM_EM_WORDS)) { + dataToCL1Card1[EM_SLR1_NEG_OFFSET + cntr11neg] = mydata; + clusterCollCard1[EM_SLR1_NEG_OFFSET + cntr11neg] = cluster; + cntr11neg++; + } + if ((iGCT == 2) && isSLR1 && isNegativeEta && (cntr21neg < NUM_EM_WORDS)) { + dataToCL1Card2[EM_SLR1_NEG_OFFSET + cntr21neg] = mydata; + clusterCollCard2[EM_SLR1_NEG_OFFSET + cntr21neg] = cluster; + cntr21neg++; + } + if ((iGCT == 0) && isSLR3 && !isNegativeEta && (cntr03pos < NUM_EM_WORDS)) { + dataToCL1Card0[EM_SLR3_POS_OFFSET + cntr03pos] = mydata; + clusterCollCard0[EM_SLR3_POS_OFFSET + cntr03pos] = cluster; cntr03pos++; - goto fillend; - } - if(iGCT == 1 && cntr13pos < 16){ - dataToCL1Card1[1+cntr13pos] = mydata; - clusterCollCard1[1+cntr13pos] = cluster; + } + if ((iGCT == 1) && isSLR3 && !isNegativeEta && (cntr13pos < NUM_EM_WORDS)) { + dataToCL1Card1[EM_SLR3_POS_OFFSET + cntr13pos] = mydata; + clusterCollCard1[EM_SLR3_POS_OFFSET + cntr13pos] = cluster; cntr13pos++; - goto fillend; - } - if(iGCT == 2 && cntr23pos < 16){ - dataToCL1Card2[1+cntr23pos] = mydata; - clusterCollCard2[1+cntr23pos] = cluster; + } + if ((iGCT == 2) && isSLR3 && !isNegativeEta && (cntr23pos < NUM_EM_WORDS)) { + dataToCL1Card2[EM_SLR3_POS_OFFSET + cntr23pos] = mydata; + clusterCollCard2[EM_SLR3_POS_OFFSET + cntr23pos] = cluster; cntr23pos++; - goto fillend; } - goto fillend; - -slr3neg: ; - - if(iGCT == 0 && cntr03neg < 16){ - dataToCL1Card0[41+cntr03neg] = mydata; - clusterCollCard0[41+cntr03neg] = cluster; + if ((iGCT == 0) && isSLR3 && isNegativeEta && (cntr03neg < NUM_EM_WORDS)) { + dataToCL1Card0[EM_SLR3_NEG_OFFSET + cntr03neg] = mydata; + clusterCollCard0[EM_SLR3_NEG_OFFSET + cntr03neg] = cluster; cntr03neg++; - goto fillend; - } - if(iGCT == 1 && cntr13neg < 16){ - dataToCL1Card1[41+cntr13neg] = mydata; - clusterCollCard1[41+cntr13neg] = cluster; - cntr13neg++; - goto fillend; - } - if(iGCT == 2 && cntr23neg < 16){ - dataToCL1Card2[41+cntr23neg] = mydata; - clusterCollCard2[41+cntr23neg] = cluster; - cntr23neg++; - goto fillend; } - goto fillend; - -slr1pos: ; - - if(iGCT == 0 && cntr01pos < 16){ - dataToCL1Card0[81+1+cntr01pos] = mydata; - clusterCollCard0[81+1+cntr01pos] = cluster; - cntr01pos++; - goto fillend; - } - if(iGCT == 1 && cntr11pos < 16){ - dataToCL1Card1[81+1+cntr11pos] = mydata; - clusterCollCard1[81+1+cntr11pos] = cluster; - cntr11pos++; - goto fillend; - } - if(iGCT == 2 && cntr21pos < 16){ - dataToCL1Card2[81+1+cntr21pos] = mydata; - clusterCollCard2[81+1+cntr21pos] = cluster; - cntr21pos++; - goto fillend; + if ((iGCT == 1) && isSLR3 && isNegativeEta && (cntr13neg < NUM_EM_WORDS)) { + dataToCL1Card1[EM_SLR3_NEG_OFFSET + cntr13neg] = mydata; + clusterCollCard1[EM_SLR3_NEG_OFFSET + cntr13neg] = cluster; + cntr13neg++; } - goto fillend; - -slr1neg: ; - - if(iGCT == 0 && cntr01neg < 16){ - dataToCL1Card0[81+41+cntr01neg] = mydata; - clusterCollCard0[81+41+cntr01neg] = cluster; - cntr01neg++; - goto fillend; - } - if(iGCT == 1 && cntr11neg < 16){ - dataToCL1Card1[81+41+cntr11neg] = mydata; - clusterCollCard1[81+41+cntr11neg] = cluster; - cntr11neg++ ; - goto fillend ; - } - if(iGCT == 2 && cntr21neg < 16){ - dataToCL1Card2[81+41+cntr21neg] = mydata; - clusterCollCard2[81+41+cntr21neg] = cluster; - cntr21neg++ ; - goto fillend ; + if ((iGCT == 2) && isSLR3 && isNegativeEta && (cntr23neg < NUM_EM_WORDS)) { + dataToCL1Card2[EM_SLR3_NEG_OFFSET + cntr23neg] = mydata; + clusterCollCard2[EM_SLR3_NEG_OFFSET + cntr23neg] = cluster; + cntr23neg++; } - -fillend: ; } } } - l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18 = l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card0, dataToCL1Card1, dataToCL1Card2, clusterCollCard0, clusterCollCard1, clusterCollCard2) ; - caloCandsTMI18->push_back(l1CaloTMI18) ; + l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_0 = + l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card0, clusterCollCard0); + l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_1 = + l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card1, clusterCollCard1); + l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_2 = + l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card2, clusterCollCard2); + + caloCandsTMI18->push_back(l1CaloTMI18_0); + caloCandsTMI18->push_back(l1CaloTMI18_1); + caloCandsTMI18->push_back(l1CaloTMI18_2); evt.put(std::move(caloCandsTMI18), "DigitizedCaloToCorrelatorTMI18"); - - } +} // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void Phase2L1CaloToCorrelatorTMI18::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; - desc.add("gctEmDigiClusters", edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters")); - desc.add("gctHadDigiClusters", edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTHadDigiClusters")); + desc.add("gctEmDigiClusters", + edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters")); + desc.add("gctHadDigiClusters", + edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTHadDigiClusters")); descriptions.addWithDefaultLabel(desc); } diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index c4691d19deb3c..2f4f3f89e6654 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -33,7 +33,6 @@ #include #include #include -#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h" #include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" // @@ -163,27 +162,21 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Check if this cluster falls into each SLR region, i.e. if the cluster is within 120/2 = 60 degrees of the center of the SLR in phi float clusterRealPhiAsDegree = clusterIn.realPhi() * 180 / M_PI; float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); - if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region - // Go from real phi to an index in the SLR - // The crystal directly above the region center in phi, is iPhi 0. The crystal directly below the region center in phi, is iPhi -1. - int iPhiCrystalDifference = std::floor(phiDifference); - - // For eta, the eta is already digitized, just needs to be converted from [0, +2*17*5) to [-17*5, +17*5) + if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region + // The eta is already digitized, just needs to be converted from [0, +2*17*5) to [-17*5, +17*5) int temp_iEta_signed = clusterIn.eta() - (p2eg::CRYSTALS_IN_TOWER_ETA * p2eg::n_towers_per_link); - // Sascha eta and phi already implemented in digi collection in Phase2L1CaloEGammaUtils.h - // Need to adapt DigitizedClusterCorrelator to DigitizedClusterCorrelatorTM18 - l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), + // Need to adapt DigitizedClusterCorrelator to DigitizedClusterCorrelatorTM18 + l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), clusterIn.eta(), clusterIn.phi(), - ap_uint<6>(0x3F) , - ap_uint<6>(0x3F) , - ap_uint<6>(0x3F) , - ap_uint<3>(0x7) , - ap_uint<5>(0x1F), - ap_uint<2>(0x2), - ap_uint<10>(0x3FF) , - 0, true ) ; + clusterIn.hoe(), + clusterIn.iso(), + clusterIn.shape(), + clusterIn.wp(), + clusterIn.timing(), + clusterIn.brems(), + clusterIn.spare()); // there is a 1-to-1 mapping between the original float clusters and the first step of digitization, so we can build a ref to the same cluster edm::Ref thisRef(inputGCTClusters, iCluster); @@ -194,11 +187,11 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Check which RCT card this falls into, ordered 0, 1, 2, 3 counting from the most negative phi (real phi or iPhi) to the most positive // so RCT card 0 is -60 to -30 degrees in phi from the center, RCT card 1 is -30 to 0 degrees in phi from the center, RCT card 2 is 0 to +30 degrees in phi from the center, RCT card 3 is +30 to +60 degrees in phi from the center int whichRCTcard = 0; - if (phiDifference < -30) { + if (phiDifference < -(p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { whichRCTcard = 0; } else if (phiDifference < 0) { whichRCTcard = 1; - } else if (phiDifference < 30) { + } else if (phiDifference < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { whichRCTcard = 2; } else { whichRCTcard = 3; @@ -254,11 +247,8 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Check if this cluster falls into each GCT card float clusterRealPhiAsDegree = pfIn.clusterPhi() * 180 / M_PI; - float phiDifference = clusterRealPhiAsDegree - regionCentersInDegrees[iRegion]; - if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region - // Go from real phi to an index in the SLR - int iPhiCrystalDifference = std::floor(phiDifference); - + float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); + if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region // For PFClusters, the method clusterEta returns a float, so we need to digitize this float eta_LSB = p2eg::ECAL_eta_range / (p2eg::N_GCTTOWERS_FIBER * p2eg::CRYSTALS_IN_TOWER_ETA); int temp_iEta_signed = std::floor(pfIn.clusterEta() / eta_LSB); @@ -276,38 +266,28 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E continue; } - // Sascha eta - ap_uint<7> pf_eta = (ap_uint<7>)(abs(pfIn.clusterEta()/1.45*85)) ; - - // Sascha phi - float absphi = pfIn.clusterPhi()-0.525 ; - float phivscenter = 0; - ap_int<7> pf_phi = 0; - if(absphi>=-1.575 && absphi < -0.525) { phivscenter = absphi + 1.05 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } // first 2 bits encode slr 1 or 3 - if(absphi>=-0.525 && absphi < 0.525) { phivscenter = absphi ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} - if(absphi>=0.525 && absphi < 1.575) { phivscenter = absphi - 1.05 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} // bits 3 and 4 encode the cards 0 1 3 as 0 8 16 - if(absphi>=1.575 && absphi < 2.625) { phivscenter = absphi - 2.1 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ;} - if(absphi>=2.625 ) { phivscenter = absphi - 3.15 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } - if(absphi<-2.625) { phivscenter = absphi + 3.15 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } - if(absphi>=-2.625 && absphi < -1.575) { phivscenter = absphi + 2.1 ; pf_phi = (ap_int<7>)(phivscenter/0.525*30) ; } + ap_uint<7> pf_eta = (ap_uint<7>)((abs(pfIn.clusterEta()) - (eta_LSB / 2)) / eta_LSB); + ap_int<7> pf_phi = 0x7F & int(std::floor(phiDifference)); // greatest integer <= x // Initialize the new cluster - ap_uint<20> spare = 0 ; - if(temp_iEta_signed < 0) spare = 4; // 3rd bit encode PosEta - ap_uint<12> pf_et = (ap_uint<12>)(pfIn.clusterEt() / p2eg::ECAL_LSB); - l1tp2::GCTHadDigiCluster pfOut = l1tp2::GCTHadDigiCluster(pf_et, pf_eta, pf_phi, pf_et, 0x3F, spare, 0, true); + ap_uint<36> spare = 0; + if (temp_iEta_signed < 0) + spare = 4; // 3rd bit encode PosEta + ap_uint<12> pf_et = (ap_uint<12>)(pfIn.clusterEt() / p2eg::ECAL_LSB); + ap_uint<12> pf_ecal = (ap_uint<12>)(pfIn.ecalEt() / p2eg::ECAL_LSB); + l1tp2::GCTHadDigiCluster pfOut = l1tp2::GCTHadDigiCluster(pf_et, pf_eta, pf_phi, pf_ecal, 0x3F, spare); pfOut.setRef(edm::Ref(inputPFClusters, iCluster)); // Check which RCT card this falls into, ordered 0, 1, 2, 3 counting from the most negative phi (real phi or iPhi) to the most positive // so RCT card 0 is -60 to -30 degrees in phi from the center, RCT card 1 is -30 to 0 degrees in phi from the center, RCT card 2 is 0 to +30 degrees in phi from the center, RCT card 3 is +30 to +60 degrees in phi from the center - + int whichRCTcard = 0; - if (phiDifference < -30) { + if (phiDifference < -(p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { whichRCTcard = 0; } else if (phiDifference < 0) { whichRCTcard = 1; - } else if (phiDifference < 30) { + } else if (phiDifference < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { whichRCTcard = 2; } else { whichRCTcard = 3; @@ -421,7 +401,6 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E out_had_GCT3_SLR1_negEta.push_back(buffer_had_GCT3_SLR1_negEta[iRCT][iCluster]); out_had_GCT3_SLR3_posEta.push_back(buffer_had_GCT3_SLR3_posEta[iRCT][iCluster]); out_had_GCT3_SLR3_negEta.push_back(buffer_had_GCT3_SLR3_negEta[iRCT][iCluster]); - } } From afbd87209cec35418c2594b26628848fdd69158c Mon Sep 17 00:00:00 2001 From: pallabidas Date: Sun, 8 Feb 2026 22:48:51 +0100 Subject: [PATCH 20/92] geometry fixes for EG and PF cluster digis --- .../interface/DigitizedClusterCorrelator.h | 9 +++++++-- .../L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 6 +++--- .../interface/Phase2L1CaloPFClusterEmulator.h | 4 ++-- .../L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc | 2 +- .../plugins/Phase2L1CaloPFClusterEmulator.cc | 6 +++--- .../plugins/Phase2L1TCaloBarrelToCorrelator.cc | 5 +++-- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h index 5d02c6c4a6945..65ac055bec285 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h @@ -88,9 +88,14 @@ namespace l1tp2 { // which GCT card (0, 1, or 2) unsigned int cardNumber() const { return idxGCTCard; } - // Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841. + // Get real eta (does not depend on card number) // LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta - float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA) + (LSB_ETA / 2)); } + float realEta() const { + float tmpeta = (eta() * LSB_ETA) + (LSB_ETA / 2); + if ((spare() & 0x4) == 0) + tmpeta = -((eta() * LSB_ETA) + (LSB_ETA / 2)); + return tmpeta; + } // Get real phi (uses card number). float realPhi() const { diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 47494cc2a1b76..f8d4f79e3e04f 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1273,11 +1273,11 @@ namespace p2eg { l1tp2::DigitizedClusterCorrelator createDigitizedClusterCorrelator(const int corrTowPhiOffset) const { ap_uint<7> abseta = 0; ap_uint<10> spare = 0; - if (globalClusteriEta() > n_towers_cardEta * CRYSTALS_IN_TOWER_ETA) { - abseta = globalClusteriEta() - n_towers_cardEta * CRYSTALS_IN_TOWER_ETA; + if (globalClusteriEta() >= n_towers_cardEta * CRYSTALS_IN_TOWER_ETA) { + abseta = globalClusteriEta() - n_towers_cardEta * CRYSTALS_IN_TOWER_ETA; // 0 to 84 spare = 4; } else { - abseta = n_towers_cardEta * CRYSTALS_IN_TOWER_ETA - globalClusteriEta(); + abseta = n_towers_cardEta * CRYSTALS_IN_TOWER_ETA + 1 - globalClusteriEta(); // 84 to 0 spare = 0; } diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h index da08b712c87ea..ff5468355d85c 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloPFClusterEmulator.h @@ -290,8 +290,8 @@ namespace gctpf { GCTint_t regionMax = getPeakPosition(region); std::pair pfcluster_et = getEt(temporary, regionMax.eta, regionMax.phi); - float pfcluster_eta = regionMax.eta - 2 + etaoffset; - float pfcluster_phi = regionMax.phi - 2 + phioffset; + float pfcluster_eta = regionMax.eta + etaoffset; + float pfcluster_phi = regionMax.phi + phioffset; RemoveTmp(temporary, regionMax.eta, regionMax.phi); diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc index d55b8faf2485a..eb50b56cc9a54 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloJetEmulator.cc @@ -237,7 +237,7 @@ void Phase2L1CaloJetEmulator::produce(edm::Event& iEvent, const edm::EventSetup& for (const l1tp2::CaloTower& i : *caloTowerCollection) { int ieta = i.towerIEta(); int iphi = i.towerIPhi(); - if (i.ecalTowerEt() > 1. || i.hcalTowerEt() > 1.) + if (i.ecalTowerEt() + i.hcalTowerEt() > 1.) GCTintTowers[ieta][iphi] = i.ecalTowerEt() + i.hcalTowerEt(); // suppress <= 1 GeV towers else GCTintTowers[ieta][iphi] = 0; diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc index 8d834d38c7d1b..cf6e7bf70f60c 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc @@ -146,7 +146,7 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event std::pair temporary[nTowerEtaSLR][nTowerPhiSLR]; int etaoffset = 0; - int phioffset = 0; + int phioffset = -2; //Use same code from firmware for finding clusters for (int k = 0; k < nSLR; k++) { @@ -156,7 +156,7 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event } } if (k % 2 == 0) - etaoffset = 0; + etaoffset = -2; else etaoffset = nTowerEta / 2 - 2; if (k > 1 && k % 2 == 0) @@ -183,7 +183,7 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event edm::Handle hfHandle; if (!iEvent.getByToken(hfToken_, hfHandle)) - edm::LogError("Phase2L1CaloJetEmulator") << "Failed to get HcalTrigPrimDigi for HF!"; + edm::LogError("Phase2L1CaloPFClusterEmulator") << "Failed to get HcalTrigPrimDigi for HF!"; iEvent.getByToken(hfToken_, hfHandle); float hfTowers[2 * nHfEta][nHfPhi]; // split 12 -> 24 diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index 2f4f3f89e6654..93d1d04cdf906 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -163,8 +163,9 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E float clusterRealPhiAsDegree = clusterIn.realPhi() * 180 / M_PI; float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region - // The eta is already digitized, just needs to be converted from [0, +2*17*5) to [-17*5, +17*5) - int temp_iEta_signed = clusterIn.eta() - (p2eg::CRYSTALS_IN_TOWER_ETA * p2eg::n_towers_per_link); + // Use realEta() to determine which link + float eta_LSB = p2eg::ECAL_eta_range / (p2eg::N_GCTTOWERS_FIBER * p2eg::CRYSTALS_IN_TOWER_ETA); + int temp_iEta_signed = std::floor(clusterIn.realEta() / eta_LSB); // Need to adapt DigitizedClusterCorrelator to DigitizedClusterCorrelatorTM18 l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), From 17f6ec690b0743d7502b7015d82a2013cdbe47d1 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 11 Feb 2026 17:46:51 -0600 Subject: [PATCH 21/92] fix compilation --- .../plugins/L1TCorrelatorLayer1Producer.cc | 46 +++++++++---------- .../PFClusterProducerFromL1EGClusters.cc | 6 +-- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 76e62c7a39dda..4572f8a7c4715 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -48,17 +48,12 @@ #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" -// FIXME! These are the old TM6 ones -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" +//#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" +//#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" -constexpr unsigned int calomapping[] = {3, 0, 9, 6, 4, 1, 10, 7, 5, 2, 11, 8}; -// regions order: GCT1 SLR1, GCT1 SLR3, GCT2 SLR1, GCT2 SLR3, GCT3 SLR1, GCT3SLR3 -// phi center: 10 70 130 -170 -110 -50 -// eta: + - //-------------------------------------------------------------------------------------------------- class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { @@ -87,8 +82,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { edm::EDGetTokenT hadHGCalCands_; // can alternately give the raw containers (for GCT) - // FIXME! These should be all the candidates, not just Em - edm::EDGetTokenT gctRawCands_; + edm::EDGetTokenT gctRawCands_; float emPtCut_, hadPtCut_; @@ -154,7 +148,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { // GCT input clusters void addGCTHadCalo(const l1t::PFCluster &calo, const edm::Ptr &caloPtr); // for GCT raw calos as input (FIXME) - void addGCTCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); + void addGCTCaloRaw(const l1tp2::GCTDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); //void addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); // add objects in already-decoded format void addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t); @@ -280,17 +274,19 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet throw cms::Exception("Configuration", "Unsupported hgcalInputConversionAlgo"); } const std::string &gctEmInAlgo = iConfig.getParameter("gctEmInputConversionAlgo"); + const std::string &gctHadInAlgo = iConfig.getParameter("gctHadInputConversionAlgo"); const edm::InputTag gctClusters = iConfig.getParameter("gctClusters"); if (!gctClusters.label().empty()) { + if (gctEmInAlgo == "Emulator" || gctHadInAlgo == "Emulator") { + gctRawCands_ = consumes(gctClusters); + } if (gctEmInAlgo == "Emulator") { gctEmInput_ = std::make_unique( // FIXME iConfig.getParameter("gctInputConversionParameters")); - gctRawCands_ = consumes(gctClusters); // FIXME } else if (gctEmInAlgo != "None") { throw cms::Exception("Configuration", "Unsupported gctEmInputConversionAlgo"); } } - const std::string &gctHadInAlgo = iConfig.getParameter("gctHadInputConversionAlgo"); if (!gctClusters.label().empty() && gctHadInAlgo == "Emulator") { gctHadInput_ = std::make_unique( iConfig.getParameter("gctHadInputConversionParameters")); @@ -537,9 +533,9 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe auto caloHandle = iEvent.getHandle(gctRawCands_); const auto &links = *caloHandle; for (unsigned int ic = 0; ic < links.size(); ++ic) { - const auto &link = links[ic]; + const auto &link = links[ic].linkCard(); for (unsigned int ie = 0; ie < link.size(); ++ie) { - addGCTCaloRaw(link, ic, ie); // FIXME? + addGCTCaloRaw(link, ic, ie); } } } @@ -1000,14 +996,18 @@ void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster & } } -void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTEmDigiClusterLink &link, - unsigned int linkidx, - unsigned int entidx) { - // in the "Ideal" regionizer, ignore the second set that is sent; only use the first - auto caloIdx = calomapping[linkidx]; - if (caloIdx < event_.raw.gctcluster.size()) { - event_.raw.gctcluster[caloIdx].obj.push_back(link[entidx].data()); - addDecodedGCTEmCalo(event_.decoded.emcalo[caloIdx], link[entidx]); // FIXME +void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTDigiClusterLink &link, + unsigned int linkidx, + unsigned int entidx) { + if (auto p = std::get_if(&link[entidx])) { + event_.raw.gctcluster[linkidx].obj.push_back(p->data()); + addDecodedGCTEmCalo(event_.decoded.emcalo[linkidx], *p); + } else if (auto p = std::get_if(& link[entidx])) { + event_.raw.gctcluster[linkidx].obj.push_back(p->data()); + addDecodedGCTHadCalo(event_.decoded.hadcalo[linkidx], *p); + } else { + // this is the extra data that is neither had nor em + event_.raw.gctcluster[linkidx].obj.push_back(0); // the value should not be used } } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc index 149b4ca8c5315..ecbbd85a85130 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc @@ -88,8 +88,7 @@ void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const // bit 0: standaloneWP: is_iso && is_ss // bit 1: looseL1TkMatchWP: is_looseTkiso && is_looseTkss // bit 2: photonWP: - unsigned int qual = (digiCryCl.passes_iso() && digiCryCl.passes_ss()) | - ((digiCryCl.passes_looseTkiso() && digiCryCl.passes_looseTkss()) << 1) | (false << 2); + unsigned int qual = digiCryCl.wp(); cluster.setHwQual(qual); // cluster.setDigiWord(digiCryCl.data()); out->push_back(cluster); @@ -109,8 +108,7 @@ void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const if (corrector_.valid()) corrector_.correctPt(cluster); cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); - unsigned int qual = (digiCryCl.passes_iso() && digiCryCl.passes_ss()) | - ((digiCryCl.passes_looseTkiso() && digiCryCl.passes_looseTkss()) << 1) | (false << 2); + unsigned int qual = digiCryCl.wp(); cluster.setHwQual(qual); // cluster.setDigiWord(digiCryCl.data()); From e0255753a62a405375d2a2d457bf49d68ed75544 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 12 Feb 2026 12:17:43 -0600 Subject: [PATCH 22/92] remove commented out code --- .../plugins/L1TCorrelatorLayer1Producer.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 4572f8a7c4715..ca1814b0bed20 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -551,18 +551,6 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe } } - // FIXME - // if (!hadGCTRawCands_.isUninitialized()) { - // auto caloHandle = iEvent.getHandle(hadGCTRawCands_); - // const auto &links = *caloHandle; - // for (unsigned int ic = 0; ic < links.size(); ++ic) { - // const auto &link = links[ic]; - // for (unsigned int ie = 0; ie < link.size(); ++ie) { - // addGCTHadCaloRaw(link, ic, ie); - // } - // } - // } - if (!hadGCTCands_.isUninitialized()) { auto caloHandle = iEvent.getHandle(hadGCTCands_); if (caloHandle.isValid()) { From b3775c062c40bb7eb9b61a99693cf0f2369c0329 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 13 Feb 2026 16:56:57 -0600 Subject: [PATCH 23/92] snapshot of updating configuration --- .../L1TCorrelatorLayer1PatternFileWriter.h | 2 +- .../python/l1ctLayer1_patternWriters_cff.py | 153 ++++++------------ .../test/make_l1ct_binaryFiles_cfg.py | 8 +- 3 files changed, 52 insertions(+), 111 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h index 0302cd3e5b067..405b727b0f6eb 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -33,7 +33,7 @@ class L1TCorrelatorLayer1PatternFileWriter { const unsigned int hgcTmuxFactor_ = 18, hgcLinksFactor_ = 4; const unsigned int gctTmuxFactor_ = 18, gctEmLinksFactor_ = 1; const unsigned int gmtTmuxFactor_ = 18, gmtLinksFactor_ = 1; - const unsigned int gttTmuxFactor_ = 6, gttLinksFactor_ = 1; + const unsigned int gttTmuxFactor_ = 18, gttLinksFactor_ = 1; const unsigned int tfTimeslices_, hgcTimeslices_, gctTimeslices_, gmtTimeslices_, gttTimeslices_; uint32_t gctLinksEcal_, gctLinksHad_; bool gctSingleLink_; diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index bc3ba02ebc965..9eb452a23a782 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -14,26 +14,28 @@ nEgammaObjectsOut = cms.uint32(16), nInputFramesPerBX = cms.uint32(9), nOutputFramesPerBX = cms.uint32(9), - fileFormat = cms.string("EMPv2"), + fileFormat = cms.string("APx"), inputFileExtension = cms.string("txt.gz"), outputFileExtension = cms.string("txt.gz"), maxLinesPerInputFile = cms.uint32(1024), maxLinesPerOutputFile = cms.uint32(1024), eventsPerFile = cms.uint32(_eventsPerFile), - tfTimeSlices = cms.VPSet(), - gmtTimeSlices = cms.VPSet(), gmtNumberOfMuons = cms.uint32(12), + gmtLink = cms.int32(-1), + gctLinks = cms.vint32(-1), + tfLinks = cms.vint32(-1), gttLink = cms.int32(-1), - gttLatency = cms.uint32(156+10), + gttLatency = cms.uint32(167), gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), - gctEmSectors = cms.VPSet(), - gctHadSectors = cms.VPSet(), tfNumberOfTracks = cms.uint32(108), gctNumberOfObjects = cms.uint32(162), + outputRegions = cms.vuint32(*range(54)), + outputBoard = cms.int32(0), ) ## Barrel (54) split in 3 phi slices (EMP format) barrelWriterOutputOnlyPhiConfigs = [ _barrelWriterOutputOnly.clone( + fileFormat = cms.string("EMPv2"), tmuxFactor = cms.uint32(6), outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(6) for i in range(3) ]), outputBoard = cms.int32(ip), @@ -41,50 +43,7 @@ ) for ip in range(3) ] -def _sortApxRegions(etaPhiSortedRegions): - """Returns the APx output order for a tuple/list of regions (ints) - """ - apxOrder = (0, 4, 2, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15, 1, 17, 3) - if len(etaPhiSortedRegions) != len(apxOrder): - raise RuntimeError(f"Unexptected number of regions passed: {len(etaPhiSortedRegions)}") - return [etaPhiSortedRegions[apxOrder[i]] for i in range(len(apxOrder))] - -## Barrel (54) split in 3 phi slices (APx format) -barrelWriterOutputOnlyPhiConfigsAPx = [ - _barrelWriterOutputOnly.clone( - fileFormat = cms.string("APx"), - outputRegions = cms.vuint32(*_sortApxRegions([3*ip+9*ie+i for ie in range(6) for i in range(3) ])), - outputBoard = cms.int32(ip), - outputFileName = cms.string("l1BarrelApxPhi%d-outputs" % (ip+1)) - ) for ip in range(3) -] - -barrelWriterDebugPFInConfigsAPx = [ - _barrelWriterOutputOnly.clone( - fileFormat = cms.string("APx"), - outputRegions = cms.vuint32(*_sortApxRegions([3*ip+9*ie+i for ie in range(6) for i in range(3) ])), - outputBoard = cms.int32(ip), - nPFInTrack = cms.uint32(22), - nPFInEmCalo = cms.uint32(12), - nPFInHadCalo = cms.uint32(15), - nPFInMuon = cms.uint32(2), - debugFileName = cms.string("l1BarrelApxPhi%d-pfin" % (ip+1)) - ) for ip in range(3) -] - -barrelWriterDebugPFOutConfigsAPx = [ - _barrelWriterOutputOnly.clone( - fileFormat = cms.string("APx"), - outputRegions = cms.vuint32(*_sortApxRegions([3*ip+9*ie+i for ie in range(6) for i in range(3) ])), - outputBoard = cms.int32(ip), - nPFOutCharged = cms.uint32(22), - nPFOutPhoton = cms.uint32(12), - nPFOutNeutral = cms.uint32(15), - nPFOutMuon = cms.uint32(2), - debugFileName = cms.string("l1BarrelApxPhi%d-pfout" % (ip+1)) - ) for ip in range(3) -] - +# I do not think these work any more, particularly for the gct barrelSerenityPhi1Config = barrelWriterOutputOnlyPhiConfigs[0].clone( tfTimeSlices = cms.VPSet(*[cms.PSet(tfSectors = cms.VPSet(*[ cms.PSet(tfLink = cms.int32(-1)) for s in range(18) ])) for t in range(3)]), gctEmSectors = cms.VPSet(*[ cms.PSet(gctEmLink = cms.int32(-1)) for s in range(12) ]), @@ -102,62 +61,8 @@ def _sortApxRegions(etaPhiSortedRegions): inputFileName = cms.string("l1BarrelPhi1Serenity-inputs-vu13p"), ) -# This includes muon and GTT sector mapping. There is only one GTT fiber, with a logical firmware link of 123. -# The muons, being TM18, have three time slices, to map the emulated data to logical firmware links of 10, 48, and 107 -# Only placeholders are entered for the GCT and TF link numbers here, which are filled in the loops below -barrelApxWriterConfig = [ - _barrelWriterOutputOnly.clone( - fileFormat = cms.string("APx"), - gttLink = cms.int32(123), - gmtTimeSlices = cms.VPSet(*[cms.PSet(gmtLink = cms.int32(38*t+10)) for t in range(3)]), - gctEmSectors = cms.VPSet(*[ cms.PSet(gctEmLink = cms.int32(-1)) for s in range(12) ]), - gctHadSectors = cms.VPSet(*[ cms.PSet(gctHadLink = cms.int32(-1)) for s in range(12) ]), - inputFileName = cms.string("l1BarrelApxPhi%d-inputs" % (ip+1)), - tfTimeSlices = cms.VPSet(*[cms.PSet(tfSectors = cms.VPSet(*[ cms.PSet(tfLink = cms.int32(-1)) for s in range(18) ])) for t in range(3)]), - ) for ip in range(3) -] - -# Set GCT link numbers. 115-122 are the logical fiber numbers in the firmware. -# This maps the emulated sector indices to the firmware logical numbers -# Note, since both the GCT and CL1 are TM6 in this case, there are no time slices -for iBigRegion, ilink in enumerate((0, 1, 2)): - barrelApxWriterConfig[iBigRegion].gctEmSectors[ilink].gctEmLink = 119 - barrelApxWriterConfig[iBigRegion].gctEmSectors[ilink+6].gctEmLink = 120 - barrelApxWriterConfig[iBigRegion].gctEmSectors[ilink+3].gctEmLink = 121 - barrelApxWriterConfig[iBigRegion].gctEmSectors[ilink+9].gctEmLink = 122 - barrelApxWriterConfig[iBigRegion].gctHadSectors[ilink].gctHadLink = 115 - barrelApxWriterConfig[iBigRegion].gctHadSectors[ilink+6].gctHadLink = 116 - barrelApxWriterConfig[iBigRegion].gctHadSectors[ilink+3].gctHadLink = 117 - barrelApxWriterConfig[iBigRegion].gctHadSectors[ilink+9].gctHadLink = 118 - -# Set tracking link numbers. The tracks are logically 0-9, 38-47, and 76-85 for TM groups 0, 1, and 2 in the firmware -# This maps the emulated sector indices to the firmware logical numbers -for timeSlice in range(3): - for iBigRegion, ilink in enumerate((8, 2, 5)): - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[ilink].tfLink = 0 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[(ilink+1)%9].tfLink = 1 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[(ilink+2)%9].tfLink = 2 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[(ilink+3)%9].tfLink = 3 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[(ilink+4)%9].tfLink = 4 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[9 + ilink].tfLink = 5 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[9 + (ilink+1)%9].tfLink = 6 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[9 + (ilink+2)%9].tfLink = 7 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[9 + (ilink+3)%9].tfLink = 8 + timeSlice * 38 - barrelApxWriterConfig[iBigRegion].tfTimeSlices[timeSlice].tfSectors[9 + (ilink+4)%9].tfLink = 9 + timeSlice * 38 - -# Similar mapping for the barrel Serenity setup -for t in range(3): - for ie in range(2): - for i,s in enumerate([8, 0, 1, 2, 3]): - loglink = 3*(i+5*ie)+t - physlink = loglink+4*1 if loglink < 15 else (loglink-15)+4*25 - barrelSerenityVU9PPhi1Config.tfTimeSlices[t].tfSectors[s+9*ie].tfLink = physlink - physlink = loglink+4*0 if loglink < 15 else (loglink-15)+4*28 - barrelSerenityVU13PPhi1Config.tfTimeSlices[t].tfSectors[s+9*ie].tfLink = physlink barrelWriterConfigs = barrelWriterOutputOnlyPhiConfigs -barrelOutputWriterConfigsAPx = barrelWriterOutputOnlyPhiConfigsAPx -barrelInputWriterConfigsAPx = barrelApxWriterConfig ##################################################################################################################### ## HGcal configuration: write out both inputs and outputs @@ -290,10 +195,9 @@ def _sortApxRegions(etaPhiSortedRegions): ##################################################################################################################### ## TM18 configuration _barrelSerenityTM18 = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("EMPv2"), tmuxFactor = cms.uint32(18), - tfTimeSlices = None, tfSectors = cms.VPSet(*[cms.PSet(tfLink = cms.int32(-1)) for i in range(18)]), - gmtTimeSlices = None, gmtLink = cms.int32(4*18+0), gttLink = 4*28+3, eventsPerFile = 4, @@ -321,6 +225,43 @@ def _sortApxRegions(etaPhiSortedRegions): barrelSerenityVU13PTM18WriterConfig ] +## Barrel (54) TM18 (APx format) +barrelWriterOutputOnlyPhiConfigsAPx = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("APx"), + outputFileName = cms.string("l1BarrelApx-outputs") +) + +barrelWriterDebugPFInConfigsAPx = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("APx"), + nPFInTrack = cms.uint32(22), + nPFInEmCalo = cms.uint32(12), + nPFInHadCalo = cms.uint32(15), + nPFInMuon = cms.uint32(2), + debugFileName = cms.string("l1BarrelApx-pfin") +) + +barrelWriterDebugPFOutConfigsAPx = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("APx"), + nPFOutCharged = cms.uint32(22), + nPFOutPhoton = cms.uint32(12), + nPFOutNeutral = cms.uint32(15), + nPFOutMuon = cms.uint32(2), + debugFileName = cms.string("l1BarrelApx-pfout") +) + +# This includes the tracker, GCT, muon and GTT sector mapping. There is only one GTT fiber, with a logical firmware link of 123. +barrelApxWriterConfig = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("APx"), + gttLink = cms.int32(123), + gmtLink = cms.int32(21), + gctLinks = cms.vint32(18, 19, 20), + tfLinks = cms.vint32(*range(18)), + inputFileName = cms.string("l1BarrelApx-inputs") +) + +barrelOutputWriterConfigsAPx = barrelWriterOutputOnlyPhiConfigsAPx +barrelInputWriterConfigsAPx = barrelApxWriterConfig + _hgcalWriterTM18 = _hgcalWriterConfig.clone( tmuxFactor = cms.uint32(18), tfTimeSlices = None, diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 6ea272cccdfa4..9e9bc69c10aab 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -197,10 +197,10 @@ from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import _eventsPerFile if not args.patternFilesOFF: process.l1tLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) - process.l1tLayer1BarrelTDR.patternWriters = cms.untracked.VPSet(*barrelInputWriterConfigsAPx, - *barrelOutputWriterConfigsAPx, - *barrelWriterDebugPFInConfigsAPx, - *barrelWriterDebugPFOutConfigsAPx + process.l1tLayer1BarrelTDR.patternWriters = cms.untracked.VPSet(barrelInputWriterConfigsAPx, + barrelOutputWriterConfigsAPx, + barrelWriterDebugPFInConfigsAPx, + barrelWriterDebugPFOutConfigsAPx ) process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) process.l1tLayer1BarrelSerenityElliptic.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) From bfc52833cac8a47592b88a9e2ed13fb08ea36edb Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 13 Feb 2026 18:26:39 -0600 Subject: [PATCH 24/92] a few more configuration fixes --- .../plugins/L1TCorrelatorLayer1Producer.cc | 2 +- L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index ca1814b0bed20..dcc12b97533c8 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -282,7 +282,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet } if (gctEmInAlgo == "Emulator") { gctEmInput_ = std::make_unique( // FIXME - iConfig.getParameter("gctInputConversionParameters")); + iConfig.getParameter("gctEmInputConversionParameters")); } else if (gctEmInAlgo != "None") { throw cms::Exception("Configuration", "Unsupported gctEmInputConversionAlgo"); } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index ab743b30ebd5e..b52959ee6045a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -13,7 +13,7 @@ l1tLayer1Barrel = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','prompt'), - emClusters = cms.InputTag('l1tPhase2GCTBarrelToCorrelatorLayer1Emulator', 'GCTEmDigiClusters'), + gctClusters = cms.InputTag("l1tPhase2CaloToCorrelatorTMI18", "DigitizedCaloToCorrelatorTMI18"), hadClusters = cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated'), # hadClusters = cms.InputTag('l1tPhase2GCTBarrelToCorrelatorLayer1Emulator', 'GCTHadDigiClusters'), vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), @@ -152,7 +152,6 @@ l1tLayer1HGCal = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','prompt'), - emClusters = cms.InputTag(""), # the em clusters are "intercepted" from the had ones in the regionizer hadClusters = cms.InputTag("l1tHGCalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering"), vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), nVtx = cms.int32(1), @@ -323,7 +322,6 @@ l1tLayer1HGCalNoTK = cms.EDProducer("L1TCorrelatorLayer1Producer", muons = cms.InputTag('l1tSAMuonsGmt','prompt'), - emClusters = cms.InputTag(""), hadClusters = cms.InputTag("l1tHGCalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering"), vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), nVtx = cms.int32(1), @@ -439,7 +437,6 @@ l1tLayer1HF = cms.EDProducer("L1TCorrelatorLayer1Producer", muons = cms.InputTag('l1tSAMuonsGmt','prompt'), - emClusters = cms.InputTag(''), hadClusters = cms.InputTag('l1tPFClustersFromCombinedCaloHF:calibrated'), gctHadInputConversionAlgo = cms.string("Ideal"), vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), From fd27e9fad9467b83dfef32d7bd95bad4ef4a9633 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 16 Feb 2026 00:19:43 -0600 Subject: [PATCH 25/92] updates to using alt tdr regionizer --- .../plugins/L1TCorrelatorLayer1Producer.cc | 6 ++--- .../python/l1ctLayer1_patternWriters_cff.py | 8 +++---- .../src/regionizer/tdr_alt_regionizer_ref.cpp | 2 ++ .../test/make_l1ct_binaryFiles_cfg.py | 23 ++++++------------- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index dcc12b97533c8..193b1dde7248c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -31,7 +31,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h" @@ -314,7 +314,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); } else if (regalgo == "TDR") { - regionizer_ = std::make_unique( + regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); } else throw cms::Exception("Configuration", "Unsupported regionizerAlgo"); @@ -416,7 +416,7 @@ void L1TCorrelatorLayer1Producer::fillDescriptions(edm::ConfigurationDescription "Emulator" >> getParDesc("gctHadInputConversion")); // Regionizer auto idealRegPD = getParDesc("regionizerAlgo"); - auto tdrRegPD = getParDesc("regionizerAlgo"); + auto tdrRegPD = getParDesc("regionizerAlgo"); auto multififoRegPD = getParDesc("regionizerAlgo"); auto bfMultififoRegPD = getParDesc("regionizerAlgo"); auto multififoBarrelRegPD = edm::ParameterDescription( diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 9eb452a23a782..cf00e5580a3be 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -22,8 +22,8 @@ eventsPerFile = cms.uint32(_eventsPerFile), gmtNumberOfMuons = cms.uint32(12), gmtLink = cms.int32(-1), - gctLinks = cms.vint32(-1), - tfLinks = cms.vint32(-1), + gctSectors = cms.VPSet(), + tfSectors = cms.VPSet(), gttLink = cms.int32(-1), gttLatency = cms.uint32(167), gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), @@ -254,8 +254,8 @@ fileFormat = cms.string("APx"), gttLink = cms.int32(123), gmtLink = cms.int32(21), - gctLinks = cms.vint32(18, 19, 20), - tfLinks = cms.vint32(*range(18)), + gctSectors = cms.VPSet(*[cms.PSet(gctLink = cms.int32(i)) for i in (18, 19, 20)]), + tfSectors = cms.VPSet(*[cms.PSet(tfLink = cms.int32(i)) for i in range(18)]), inputFileName = cms.string("l1BarrelApx-inputs") ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp index d5f7c22de3acc..be674ebe9b0d9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp @@ -78,6 +78,8 @@ void l1ct::TDRAltRegionizerEmulator::initSectorsAndRegions(const RegionizerDecod hadCaloRegionizers_.initRegions(out); emCaloRegionizers_.initSectors(in.emcalo); emCaloRegionizers_.initRegions(out); + muRegionizers_.initSectors(in.muon); + muRegionizers_.initRegions(out); } void l1ct::TDRAltRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 9e9bc69c10aab..cb670a3ceef08 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -116,12 +116,8 @@ nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), nMu = cms.uint32(2), - nClocks = cms.uint32(162), - doSort = cms.bool(False), - bigRegionEdges = cms.vint32(-560, -560), - netaInBR = cms.uint32(6), - nphiInBR = cms.uint32(9), - debug = cms.untracked.bool(True) + debug = cms.untracked.bool(True), + debug_mu = cms.untracked.bool(True) ) process.l1tLayer1BarrelTDR.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelTDR.pfAlgoParameters.nSelCalo = 15 @@ -138,17 +134,12 @@ process.l1tLayer1BarrelTDR.gctHadInputConversionAlgo = cms.string("Emulator") process.l1tLayer1BarrelTDR.caloSectors = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 0, 1.5), - 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) - ) + cms.PSet( + etaBoundaries = cms.vdouble(-1.5, 1.5), + phiSlices = cms.uint32(3), + phiZero = cms.double(math.pi/18) ) +) process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() process.l1tLayer1BarrelSerenity.regionizerAlgo = "MiddleBufferMultififo" From 064cc8b282270c8074086d77ddc388051dadacd7 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 16 Feb 2026 19:21:45 -0600 Subject: [PATCH 26/92] varous bug fixes --- .../interface/L1TCorrelatorLayer1PatternFileWriter.h | 2 +- .../interface/regionizer/tdr_alt_regionizer_elements_ref.h | 3 --- .../interface/regionizer/tdr_alt_regionizer_elements_ref.icc | 2 +- L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h index 405b727b0f6eb..0302cd3e5b067 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -33,7 +33,7 @@ class L1TCorrelatorLayer1PatternFileWriter { const unsigned int hgcTmuxFactor_ = 18, hgcLinksFactor_ = 4; const unsigned int gctTmuxFactor_ = 18, gctEmLinksFactor_ = 1; const unsigned int gmtTmuxFactor_ = 18, gmtLinksFactor_ = 1; - const unsigned int gttTmuxFactor_ = 18, gttLinksFactor_ = 1; + const unsigned int gttTmuxFactor_ = 6, gttLinksFactor_ = 1; const unsigned int tfTimeslices_, hgcTimeslices_, gctTimeslices_, gmtTimeslices_, gttTimeslices_; uint32_t gctLinksEcal_, gctLinksHad_; bool gctSingleLink_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h index cc133b4554aa5..643c357076c0c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -138,9 +138,6 @@ namespace l1ct { /// get the logical buffer index (i.e. the index in the order in the firmware) size_t logicBuffIndex(size_t bufIdx) const; - - /// The numbers of eta and phi in a big region (board) - unsigned int neta_, nphi_; /// The maximum number of objects to output per small region unsigned int maxobjects_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index 71f58d2987bfc..2f366b6968dde 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -396,7 +396,7 @@ void l1ct::tdr_alt_regionizer::Regionizer::printDebug(int count) const { } dbgCout() << "SMALL REGIONS" << std::endl; - for (unsigned int region = 0; region < neta_ * nphi_; region++) { + for (unsigned int region = 0; region < regionmap_.size(); region++) { dbgCout() << count << "\tregion\t\titem\tpt\tloceta\tlocphi" << std::endl; auto realRegIdx = regionIndex(region); auto etaC = regions_[realRegIdx].intEtaCenter(); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index b52959ee6045a..dcbdca142a4c5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -123,7 +123,7 @@ phiSlices = cms.uint32(9), ), ), - boards = cms.VPSet( + boards = cms.VPSet( # In TM18, this is "virtual" boards for egamma cms.PSet( regions = cms.vuint32(*[0+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting cms.PSet( From 6b164ccbc9a0265ce94999a00aff9f71570eec61 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 16 Feb 2026 19:50:17 -0600 Subject: [PATCH 27/92] update calo building--had commented out too much --- .../test/make_l1ct_binaryFiles_cfg.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index cb670a3ceef08..e521d6f6d2272 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -68,10 +68,10 @@ process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') from L1Trigger.Configuration.SimL1Emulator_cff import l1tSAMuonsGmt process.l1tSAMuonsGmt = l1tSAMuonsGmt.clone() -# from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import l1tPhase2L1CaloEGammaEmulator -# process.l1tPhase2L1CaloEGammaEmulator = l1tPhase2L1CaloEGammaEmulator.clone() -# from L1Trigger.L1CaloTrigger.l1tPhase2CaloPFClusterEmulator_cfi import l1tPhase2CaloPFClusterEmulator -# process.l1tPhase2CaloPFClusterEmulator = l1tPhase2CaloPFClusterEmulator.clone() +from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import l1tPhase2L1CaloEGammaEmulator +process.l1tPhase2L1CaloEGammaEmulator = l1tPhase2L1CaloEGammaEmulator.clone() +from L1Trigger.L1CaloTrigger.l1tPhase2CaloPFClusterEmulator_cfi import l1tPhase2CaloPFClusterEmulator +process.l1tPhase2CaloPFClusterEmulator = l1tPhase2CaloPFClusterEmulator.clone() # from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator # process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() @@ -80,6 +80,8 @@ process.L1TInputTask = cms.Task( process.l1tSAMuonsGmt, + process.l1tPhase2L1CaloEGammaEmulator, + process.l1tPhase2CaloPFClusterEmulator, process.l1tPhase2CaloToCorrelatorTMI18 ) From 88538adaa3b7b7a4c5c262a402ed7cbad81cf803 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 18 Feb 2026 18:11:28 -0600 Subject: [PATCH 28/92] fix a number of logical vs physical and sorting bugs; still not fully correct --- .../tdr_alt_regionizer_elements_ref.h | 7 +- .../tdr_alt_regionizer_elements_ref.icc | 74 +++++++++++++++---- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h index 643c357076c0c..aa043de8fed21 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -50,7 +50,7 @@ namespace l1ct { Buffer() {} void addEntry(const T& obj, - std::vector srs, + std::vector srs, // LOGICAL SRs int glbeta, int glbphi); @@ -127,10 +127,11 @@ namespace l1ct { // this function is for sorting small regions first in phi and then in eta. // It takes regions_ indices bool sortRegionsRegular(size_t a, size_t b) const; + bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; + // This is for sorting sectors. It sorts in eta first, then phi bool sortSectors(size_t a, size_t b) const; - - bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; + bool sortSectorsHelper(int etaa, int etab, int phia, int phib) const; /// get the index in regions_ for a particular SR. size_t regionIndex(int sr) const { return regionmap_.at(sr); } diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index 2f366b6968dde..f95fd2f93e26b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -121,11 +121,10 @@ void l1ct::tdr_alt_regionizer::Regionizer::fillBuffers(const DetectorSector bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsRegular(size_t a, size_t b) const { - // first do eta auto etaa = regions_[a].intEtaCenter(); auto etab = regions_[b].intEtaCenter(); auto phia = regions_[a].intPhiCenter(); @@ -134,9 +133,29 @@ bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsRegular(size_t a, size_ } // this function is for sorting small regions -// in eta first, then in phi +// in phi first, then in eta template bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsHelper(int etaa, int etab, int phia, int phib) const { + // first do phi + if (phia < phib) { + return true; + } else if (phia > phib) { + return false; + } + + // Only here if have same phi + if (etaa < etab) { + return true; + } else { + return false; + } +} + +// this function is for sorting Sectors (mainly tracker) +// note it is opposite of regions to keep consistent +// It sorts in eta first, then phi +template +bool l1ct::tdr_alt_regionizer::Regionizer::sortSectorsHelper(int etaa, int etab, int phia, int phib) const { // first do eta if (etaa < etab) { return true; @@ -144,7 +163,7 @@ bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsHelper(int etaa, int et return false; } - // regular phi + // Only here if have same eta if (phia < phib) { return true; } else { @@ -161,7 +180,7 @@ bool l1ct::tdr_alt_regionizer::Regionizer::sortSectors(size_t a, size_t b) co auto etab = sectors_[b].intEtaCenter(); auto phia = sectors_[a].intPhiCenter(); auto phib = sectors_[b].intPhiCenter(); - return sortRegionsHelper(etaa, etab, phia, phib); + return sortSectorsHelper(etaa, etab, phia, phib); } template @@ -181,6 +200,14 @@ void l1ct::tdr_alt_regionizer::Regionizer::initRegions(const std::vectorsortRegionsRegular(a, b); }); + + if (debug_) { + for (auto val : regionmap_) { + dbgCout() << "regionmap_ phys index = " << val << ", eta = " << regions_[val].intEtaCenter() + << ", phi = " << regions_[val].intPhiCenter() << std::endl; + } + } + } @@ -211,9 +238,6 @@ void l1ct::tdr_alt_regionizer::Regionizer::setBuffers(const std::vector l1ct::tdr_alt_regionizer::Regionizer: // function get_small_region(index : linear_small_region_t) return eta_phi_small_region_t is // variable rval : eta_phi_small_region_t; // begin -// rval.eta_index := index / SMALL_REGION_PHI_COUNT; -// rval.phi_index := index rem SMALL_REGION_PHI_COUNT; +// rval.eta_index := index / SMALL_REGION_ETA_COUNT; +// rval.phi_index := index rem SMALL_REGION_ETA_COUNT; // return rval; // end function get_small_region; template std::pair l1ct::tdr_alt_regionizer::Regionizer::get_small_region(size_t sr) const { std::pair rval; - rval.first = sr / SMALL_REGION_PHI_COUNT; - rval.second = sr % SMALL_REGION_PHI_COUNT; + rval.second = sr / SMALL_REGION_ETA_COUNT; + rval.first = sr % SMALL_REGION_ETA_COUNT; return rval; } @@ -357,13 +389,23 @@ void l1ct::tdr_alt_regionizer::Regionizer::run() { auto links = linksForSR(sr); // these are the logical links auto physSR = regionmap_[sr]; bool allEmpty; + if (debug_) { + dbgCout() << "Starting sr = " << sr << ", physSR = " << physSR << std::endl; + } do { allEmpty = true; for (auto link : links) { auto &buffer = buffers_[sectorMapLogToPhys_[link]]; - if (!buffer.empty(physSR)) { + if (!buffer.empty(sr)) { allEmpty = false; - addToSmallRegion(physSR, buffer.getEntry(physSR)); + if (debug_) { + dbgCout() << " Link " << link << " not empty, adding it to region" << std::endl; + } + addToSmallRegion(physSR, buffer.getEntry(sr)); + } else { + if (debug_) { + dbgCout() << " Link " << link << " buffer is empty, allEmpty = " << allEmpty << std::endl; + } } } } while (!allEmpty); From 46b737232a55521544a126287870e2534919f4f0 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 18 Feb 2026 20:37:23 -0600 Subject: [PATCH 29/92] fix ieta vs iphi confusion --- .../regionizer/tdr_alt_regionizer_elements_ref.icc | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index f95fd2f93e26b..964b68cb8e8d0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -300,7 +300,7 @@ inline std::vector l1ct::tdr_alt_regionizer::Regionizer: retval.push_back(nom); retval.push_back(smaller); retval.push_back(bigger); - if (iphi == 2) { + if (ieta == 2) { // also add the other ones retval.push_back(nom + 9); retval.push_back(smaller + 9); @@ -313,7 +313,7 @@ inline std::vector l1ct::tdr_alt_regionizer::Regionizer: retval.push_back(nom); retval.push_back(smaller); retval.push_back(bigger); - if (iphi == 3) { + if (ieta == 3) { // also add the other ones retval.push_back(nom - 9); retval.push_back(smaller - 9); @@ -389,23 +389,13 @@ void l1ct::tdr_alt_regionizer::Regionizer::run() { auto links = linksForSR(sr); // these are the logical links auto physSR = regionmap_[sr]; bool allEmpty; - if (debug_) { - dbgCout() << "Starting sr = " << sr << ", physSR = " << physSR << std::endl; - } do { allEmpty = true; for (auto link : links) { auto &buffer = buffers_[sectorMapLogToPhys_[link]]; if (!buffer.empty(sr)) { allEmpty = false; - if (debug_) { - dbgCout() << " Link " << link << " not empty, adding it to region" << std::endl; - } addToSmallRegion(physSR, buffer.getEntry(sr)); - } else { - if (debug_) { - dbgCout() << " Link " << link << " buffer is empty, allEmpty = " << allEmpty << std::endl; - } } } } while (!allEmpty); From 2168cc0462826bcfa30c9e0c2760fcc84e5f3e37 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Mon, 23 Feb 2026 17:26:00 +0100 Subject: [PATCH 30/92] bug fix in calo cluster phi values, integrate PF/had clusters into Layer-1 PF algo --- .../L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h | 2 +- .../L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h | 2 +- .../L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 2 +- .../interface/l1-converters/gcthadinput_ref.h | 5 +++-- L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py | 7 +++---- .../src/l1-converters/gcthadinput_ref.cpp | 5 +++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h index afb45146b9e6a..335fba58f6d00 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -38,7 +38,7 @@ namespace l1tp2 { ap_uint<5> timing, ap_uint<2> brems, ap_uint<10> spare) { - clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | + clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)(phi & 0x7F)) << 19) | (((ap_uint<64>)hoe) << 26) | (((ap_uint<64>)iso) << 32) | (((ap_uint<64>)shape) << 38) | (((ap_uint<64>)wp) << 44) | (((ap_uint<64>)timing) << 47) | (((ap_uint<64>)brems << 52)) | (((ap_uint<64>)spare << 54)); diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h index b09073a427a1c..5404815133bae 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h @@ -26,7 +26,7 @@ namespace l1tp2 { GCTHadDigiCluster( ap_uint<12> pt, ap_uint<7> eta, ap_int<7> phi, ap_uint<12> ecal, ap_uint<6> fb, ap_uint<36> spare) { - clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 19) | + clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)(phi & 0x7F)) << 19) | (((ap_uint<64>)ecal) << 26) | (((ap_uint<64>)fb) << 38) | (((ap_uint<64>)spare << 44)); } diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index f8d4f79e3e04f..2b42db69aa5b8 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -107,7 +107,7 @@ namespace p2eg { // Returns the difference in the azimuth coordinates of phi1 and phi2 (all in degrees not radians), taking the wrap-around at 180 degrees into account inline float deltaPhiInDegrees(float phi1, float phi2, const float c = 180) { float r = std::fmod(phi1 - phi2, 2.0 * c); - if (r < -c) { + if (r <= -c) { r += 2.0 * c; } else if (r > c) { r -= 2.0 * c; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h index a0cdd28b74a17..d721c60a0fde3 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h @@ -32,8 +32,9 @@ namespace l1ct { // crystal phi (signed 7 bits) ap_int<7> phi(const ap_uint<64> &in) const { return (ap_int<7>)in.range(25, 19); } - // HoE value - ap_uint<4> hoe(const ap_uint<64> &in) const { return in.range(29, 26); } + // ECAL value + ap_uint<12> ecal(const ap_uint<64> &in) const { return (ap_uint<12>)in.range(37, 26); } + }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index dcbdca142a4c5..72d5505a220c5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -14,8 +14,7 @@ tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','prompt'), gctClusters = cms.InputTag("l1tPhase2CaloToCorrelatorTMI18", "DigitizedCaloToCorrelatorTMI18"), - hadClusters = cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated'), - # hadClusters = cms.InputTag('l1tPhase2GCTBarrelToCorrelatorLayer1Emulator', 'GCTHadDigiClusters'), + # hadClusters = cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated'), -- if you use Ideal gctHadInputConversionAlg vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), nVtx = cms.int32(1), emPtCut = cms.double(0.5), @@ -49,7 +48,7 @@ kind = cms.string('calo'), ), ), - gctHadInputConversionAlgo = cms.string("Ideal"), + gctHadInputConversionAlgo = cms.string("Emulator"), regionizerAlgo = cms.string("Ideal"), pfAlgo = cms.string("PFAlgo3"), pfAlgoParameters = cms.PSet( @@ -112,7 +111,7 @@ ), caloSectors = cms.VPSet( # for Ideal regionizer only--don't include the duplicates cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 0, 1.5), + etaBoundaries = cms.vdouble(-1.5, 1.5), phiSlices = cms.uint32(3), phiZero = cms.double(math.pi/18) ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index a7f892d3679b4..99e6dcc441c94 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -29,9 +29,10 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwPhi = l1ct::Scales::makePhi(phi(in) * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame // need to add EmPt when it becomes available + calo.hwEmPt = ecal(in) * l1ct::pt_t(0.5); - // need to add emid - calo.hwEmID = 1; + // need to add emid, default to zero for had/PF clusters from GCT + calo.hwEmID = 0; // convert eta to local if (sector.hwEtaCenter < 0) { From b970074fee55ece5527e11656cd8a14754c52aef Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 24 Feb 2026 18:21:43 -0600 Subject: [PATCH 31/92] Functioning version of TDR regionizer, but with lots of debug statements; other algorithms are commented out --- .../interface/GCTEmDigiCluster.h | 9 ++ .../interface/GCTHadDigiCluster.h | 9 ++ .../interface/l1-converters/gcteminput_ref.h | 20 ---- .../interface/l1-converters/gcthadinput_ref.h | 13 --- .../tdr_alt_regionizer_elements_ref.icc | 19 ++-- .../plugins/L1TCorrelatorLayer1Producer.cc | 96 ++++++++++++++++- .../python/l1ctLayer1_cff.py | 16 ++- .../src/l1-converters/gcteminput_ref.cpp | 15 +-- .../src/l1-converters/gcthadinput_ref.cpp | 15 ++- .../test/make_l1ct_binaryFiles_cfg.py | 101 +++++++++--------- 10 files changed, 198 insertions(+), 115 deletions(-) diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h index 335fba58f6d00..6575409031eba 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -4,8 +4,10 @@ #include #include +#ifdef CMSSW_GIT_HASH #include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" +#endif namespace l1tp2 { @@ -17,11 +19,14 @@ namespace l1tp2 { // Constants static constexpr float LSB_PT = 0.5; // 0.5 GeV + +#ifdef CMSSW_GIT_HASH // Reference to the original float cluster edm::Ref clusterRef_; // reference to the original digitized cluster (before duplication in the output links) edm::Ref digiClusterRef_; +#endif public: GCTEmDigiCluster() { clusterData = 0; } @@ -44,12 +49,14 @@ namespace l1tp2 { (((ap_uint<64>)spare << 54)); } +#ifdef CMSSW_GIT_HASH // Setters void setRef(const edm::Ref& clusterRef) { clusterRef_ = clusterRef; } void setDigiRef(const edm::Ref& digiClusterRef) { digiClusterRef_ = digiClusterRef; } +#endif // Getters ap_uint<64> data() const { return clusterData; } @@ -87,10 +94,12 @@ namespace l1tp2 { // Encoding region information ap_uint<10> spare() const { return ((clusterData >> 54) & 0x3FF); } +#ifdef CMSSW_GIT_HASH // Get the underlying float cluster const edm::Ref& clusterRef() const { return clusterRef_; } // Get the underlying digitized cluster (before duplication and zero-padding) const edm::Ref& digiClusterRef() const { return digiClusterRef_; } +#endif }; // Collection typedefs diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h index 5404815133bae..437dc3bf08513 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h @@ -4,7 +4,9 @@ #include #include +#ifdef CMSSW_GIT_HASH #include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h" +#endif namespace l1tp2 { @@ -16,8 +18,10 @@ namespace l1tp2 { // Constants static constexpr float LSB_PT = 0.5; // 0.5 GeV +#ifdef CMSSW_GIT_HASH // reference to corresponding float cluster edm::Ref clusterRef_; +#endif public: GCTHadDigiCluster() { clusterData = 0x0; } @@ -30,8 +34,11 @@ namespace l1tp2 { (((ap_uint<64>)ecal) << 26) | (((ap_uint<64>)fb) << 38) | (((ap_uint<64>)spare << 44)); } +#ifdef CMSSW_GIT_HASH // Setters void setRef(const edm::Ref& clusterRef) { clusterRef_ = clusterRef; } +#endif + // Getters ap_uint<64> data() const { return clusterData; } @@ -53,8 +60,10 @@ namespace l1tp2 { // Encoding region information ap_uint<36> spare() const { return ((clusterData >> 44) & 0xFFFFF); } +#ifdef CMSSW_GIT_HASH // Get the underlying ref const edm::Ref& clusterRef() const { return clusterRef_; } +#endif }; // Collection typedefs diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h index d97d087d4e78a..6638e60f2846e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h @@ -35,26 +35,6 @@ namespace l1ct { l1ct::EmCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; private: - ap_uint<12> pt(const ap_uint<64> &in) const { return in.range(11, 0); } - - // crystal eta (unsigned 7 bits) - ap_uint<7> eta(const ap_uint<64> &in) const { return (ap_uint<7>)in.range(18, 12); } - - // crystal phi (signed 7 bits) - ap_int<7> phi(const ap_uint<64> &in) const { return (ap_int<7>)in.range(25, 19); } - - // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) - // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass - ap_uint<2> isoFlags(const ap_uint<64> &in) const { return in.range(36, 35); } - bool passes_iso(const ap_uint<64> &in) const { return (isoFlags(in) & 0x1); } // standalone iso WP - bool passes_looseTkiso(const ap_uint<64> &in) const { return (isoFlags(in) & 0x2); } // loose Tk iso WP - - // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP - // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass - ap_uint<2> shapeFlags(const ap_uint<64> &in) const { return in.range(49, 48); } - - bool passes_ss(const ap_uint<64> &in) const { return (shapeFlags(in) & 0x1); } // standalone shower shape WP - bool passes_looseTkss(const ap_uint<64> &in) const { return (shapeFlags(in) & 0x2); } // loose Tk shower shape WP // tools for GCT clusters l1tpf::corrector corrector_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h index d721c60a0fde3..6b8cc3b1b20a6 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h @@ -22,19 +22,6 @@ namespace l1ct { l1ct::HadCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; - private: - double fracPart(const double total, const unsigned int hoe) const; - ap_uint<12> pt(const ap_uint<64> &in) const { return in.range(11, 0); } - - // crystal eta (unsigned 7 bits) - ap_uint<7> eta(const ap_uint<64> &in) const { return (ap_uint<7>)in.range(18, 12); } - - // crystal phi (signed 7 bits) - ap_int<7> phi(const ap_uint<64> &in) const { return (ap_int<7>)in.range(25, 19); } - - // ECAL value - ap_uint<12> ecal(const ap_uint<64> &in) const { return (ap_uint<12>)in.range(37, 26); } - }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index 964b68cb8e8d0..36ab3284bc04b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -323,24 +323,25 @@ inline std::vector l1ct::tdr_alt_regionizer::Regionizer: return retval; } +// slighlty more complicated because of logical index; std::vector calo_links(size_t iphi) { - if (iphi == 0) { - std::vector retval = {1}; + if (iphi < 2) { + std::vector retval = {11, 5, 6, 0, 7, 1, 8, 2}; return retval; } else if (iphi < 3) { - std::vector retval = {1, 2}; + std::vector retval = {7, 1, 8, 2}; return retval; - } else if (iphi == 3) { - std::vector retval = {2}; + } else if (iphi < 5) { + std::vector retval = {9, 3, 10, 4, 7, 1, 8, 2}; return retval; } else if (iphi < 6) { - std::vector retval = {0, 2}; + std::vector retval = {9, 3, 10, 4}; return retval; - } else if (iphi == 6) { - std::vector retval = {0}; + } else if (iphi < 8) { + std::vector retval = {9, 3, 10, 4, 11, 5, 6, 0}; return retval; } else { - std::vector retval = {0, 1}; + std::vector retval = {11, 5, 6, 0}; return retval; } } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 193b1dde7248c..ee2a12bb4c4d0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -160,6 +160,9 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { const l1ct::DetectorSector> &sec, const l1t::HGCalMulticluster &c) const; + unsigned int emDecodedIndex(unsigned int linkidx, unsigned int entidx) const; + unsigned int hadDecodedIndex(unsigned int linkidx, unsigned int entidx) const; + // fetching outputs std::unique_ptr fetchHadCalo() const; std::unique_ptr fetchEmCalo() const; @@ -273,6 +276,9 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet } else if (hgcalInAlgo != "None") throw cms::Exception("Configuration", "Unsupported hgcalInputConversionAlgo"); } + + // Note, currently do not support "Ideal" EM cluster algorithm, but one should be able to add it + // analogously to how the hadronic version is done. const std::string &gctEmInAlgo = iConfig.getParameter("gctEmInputConversionAlgo"); const std::string &gctHadInAlgo = iConfig.getParameter("gctHadInputConversionAlgo"); const edm::InputTag gctClusters = iConfig.getParameter("gctClusters"); @@ -446,6 +452,11 @@ void L1TCorrelatorLayer1Producer::fillDescriptions(edm::ConfigurationDescription caloSectorPSD.add("phiSlices", 3); caloSectorPSD.add("phiZero", 0.); desc.addVPSet("caloSectors", caloSectorPSD); + edm::ParameterSetDescription rawGCTSectorPSD; + rawGCTSectorPSD.add>("etaBoundaries"); + rawGCTSectorPSD.add("phiSlices", 3); + rawGCTSectorPSD.add("phiZero", 0.); + desc.addVPSet("rawGCTSectors", rawGCTSectorPSD, std::vector()); // raw can be packed per link // geometry: regions edm::ParameterSetDescription regionPSD; regionPSD.add>("etaBoundaries"); @@ -551,7 +562,7 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe } } - if (!hadGCTCands_.isUninitialized()) { + if (!hadGCTCands_.isUninitialized()) { // this is only for the Ideal (not Emulated) case auto caloHandle = iEvent.getHandle(hadGCTCands_); if (caloHandle.isValid()) { const auto &calos = *caloHandle; @@ -853,6 +864,8 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet event_.raw.hgcalcluster.clear(); event_.raw.gctcluster.clear(); + std::cout << "Call to initSectorsAndRegions, " << iConfig.getParameter("regionizerAlgo") << std::endl; + for (const edm::ParameterSet &preg : iConfig.getParameter("caloSectors")) { std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) @@ -868,14 +881,35 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { float phiCenter = reco::reducePhiRange(iphi * phiWidth + phiZero); + std::cout << "calo sector eta " << etaBoundaries[ieta] << " to " << etaBoundaries[ieta + 1] << ", phi " << phiCenter * 720 / M_PI << std::endl; event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); - event_.raw.gctcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); } } } + + for (const edm::ParameterSet &preg : iConfig.getParameter("rawGCTSectors")) { + std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); + if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) + throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n"); + unsigned int phiSlices = preg.getParameter("phiSlices"); + float phiWidth = 2 * M_PI / phiSlices; + if (phiWidth > 2 * l1ct::Scales::maxAbsPhi()) + throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type"); + double phiZero = preg.getParameter("phiZero"); + for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { + float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta]; + if (etaWidth > 2 * l1ct::Scales::maxAbsEta()) + throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); + for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { + float phiCenter = reco::reducePhiRange(iphi * phiWidth + phiZero); + std::cout << "raw calo sector eta " << etaBoundaries[ieta] << " to " << etaBoundaries[ieta + 1] << ", phi " << phiCenter * 720 / M_PI << std::endl; + event_.raw.gctcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); + } + } + } event_.decoded.muon.region = l1ct::PFRegionEmu(0., 0.); // centered at (0,0) event_.raw.muon.region = l1ct::PFRegionEmu(0., 0.); // centered at (0,0) @@ -984,17 +1018,67 @@ void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster & } } +// The raw to decoded index mapping is +// raw -> eta+ slr1 eta- slr1 eta+ slr3 eta1 slr3 +// 0 6 0 7 1 +// 1 8 2 9 3 +// 2 10 4 11 5 + +unsigned int L1TCorrelatorLayer1Producer::emDecodedIndex(unsigned int linkidx, unsigned int entidx) const { + if (entidx < 17) { + return 2*linkidx + 6; + } else if (entidx < 81) { + return 2*linkidx; + } else if (entidx < 98) { + return 2*linkidx + 7; + } else { + return 2*linkidx + 1; + } +} + +unsigned int L1TCorrelatorLayer1Producer::hadDecodedIndex(unsigned int linkidx, unsigned int entidx) const { + if (entidx < 57) { + return 2*linkidx + 6; + } else if (entidx < 81) { + return 2*linkidx; + } else if (entidx < 138) { + return 2*linkidx + 7; + } else { + return 2*linkidx + 1; + } +} void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTDigiClusterLink &link, unsigned int linkidx, unsigned int entidx) { if (auto p = std::get_if(&link[entidx])) { + std::cout << "GCT Raw em link " << linkidx << ", entry " << entidx << " data " + << std::hex << p->data() << std::dec << std::endl; + // (For EM don't currently suport ideal, so it is always Emulated) event_.raw.gctcluster[linkidx].obj.push_back(p->data()); - addDecodedGCTEmCalo(event_.decoded.emcalo[linkidx], *p); + if (p->pt() > 0) { + auto decidx = emDecodedIndex(linkidx, entidx); + std::cout << " adding to decoded index " << decidx << std::endl; + addDecodedGCTEmCalo(event_.decoded.emcalo[decidx], *p); + } } else if (auto p = std::get_if(& link[entidx])) { - event_.raw.gctcluster[linkidx].obj.push_back(p->data()); - addDecodedGCTHadCalo(event_.decoded.hadcalo[linkidx], *p); + std::cout << "GCT Raw had link " << linkidx << ", entry " << entidx << " data " + << std::hex << p->data() << std::dec << std::endl; + // Only do this if using Emulated GCT input, not Ideal. + if (hadGCTCands_.isUninitialized()) { + event_.raw.gctcluster[linkidx].obj.push_back(p->data()); + if (p->pt() > 0) { + auto decidx = hadDecodedIndex(linkidx, entidx); + std::cout << " adding to decoded index " << decidx << std::endl; + addDecodedGCTHadCalo(event_.decoded.hadcalo[decidx], *p); + } + } } else { // this is the extra data that is neither had nor em + std::cout << "GCT Raw null link " << linkidx << ", entry " << entidx << std::endl; + if (entidx == 1) { + auto val = std::get(link.at(entidx)); + std::cout << " The emcalo value is " << val.data() << std::endl; + } event_.raw.gctcluster[linkidx].obj.push_back(0); // the value should not be used } } @@ -1069,6 +1153,8 @@ void L1TCorrelatorLayer1Producer::addDecodedGCTEmCalo(l1ct::DetectorSectordecode(sec.region, digi.data()); + std::cout << "emclus decode " << std::hex << digi.data() << std::dec << " to pt = " << calo.hwPt << std::endl; + auto caloPtr = edm::refToPtr(digi.clusterRef()); // FIXME: should check hwPt > 0 addDecodedEmCalo(calo, caloPtr, sec); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 72d5505a220c5..13d457e3e02d2 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -109,12 +109,22 @@ tkEgSorterParameters = tkEgSorterParameters.clone( nObjToSort = 10 ), - caloSectors = cms.VPSet( # for Ideal regionizer only--don't include the duplicates + # these are the sectors for the logical "decoded" clusters; + caloSectors = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-1.5, 0, 1.5), + phiSlices = cms.uint32(6), + phiZero = cms.double(math.pi/18) + ), + ), + + # these are the sectors for the raw GCT clusters; logical sectors can be combined + rawGCTSectors = cms.VPSet( cms.PSet( etaBoundaries = cms.vdouble(-1.5, 1.5), phiSlices = cms.uint32(3), - phiZero = cms.double(math.pi/18) - ) + phiZero = cms.double(2 * math.pi/9) + ), ), regions = cms.VPSet( cms.PSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index c0891332016d8..c9d4a98bb198e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -1,4 +1,5 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -28,13 +29,17 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio constexpr float ETA_LSB = 2 * ETA_RANGE_ONE_SIDE / 170.; constexpr float PHI_LSB = 2 * M_PI / 360.; + l1tp2::GCTEmDigiCluster inclus(in); + // need to add emid l1ct::EmCaloObjEmu calo; calo.clear(); - calo.hwPt = pt(in) * l1ct::pt_t(0.5); // the LSB for GCT objects + calo.hwPt = inclus.pt() * l1ct::pt_t(inclus.ptLSB()); // the LSB for GCT objects // We add half a crystal both in eta and phi to avoid a bias - calo.hwEta = l1ct::Scales::makeGlbEta(eta(in) * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) - calo.hwPhi = l1ct::Scales::makePhi(phi(in) * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame + calo.hwEta = l1ct::Scales::makeGlbEta(inclus.eta() * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) + calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame + + calo.hwHoe = inclus.hoe(); if (corrector_.valid()) { float newpt = @@ -50,9 +55,7 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio // bit 0: standaloneWP: is_iso && is_ss // bit 1: looseL1TkMatchWP: is_looseTkiso && is_looseTkss // bit 2: photonWP: - calo.hwEmID = (passes_iso(in) && passes_ss(in)) | ((passes_looseTkiso(in) && passes_looseTkss(in)) << 1) | - ((passes_looseTkiso(in) && passes_looseTkss(in)) << 2); - + calo.hwEmID = inclus.wp(); // convert eta to local if (sector.hwEtaCenter < 0) { calo.hwEta = -calo.hwEta - sector.hwEtaCenter; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index 99e6dcc441c94..d5bdfc1f57853 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -1,4 +1,5 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -12,24 +13,22 @@ edm::ParameterSetDescription l1ct::GctHadClusterDecoderEmulator::getParameterSet } #endif -double l1ct::GctHadClusterDecoderEmulator::fracPart(const double total, const unsigned int hoe) const { - return total * std::pow(2.0, hoe) / (std::pow(2.0, hoe) + 1); -} - l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const { constexpr float ETA_RANGE_ONE_SIDE = 1.4841; // barrel goes from (-1.4841, +1.4841) constexpr float ETA_LSB = 2 * ETA_RANGE_ONE_SIDE / 170.; constexpr float PHI_LSB = 2 * M_PI / 360.; + l1tp2::GCTHadDigiCluster inclus(in); + l1ct::HadCaloObjEmu calo; calo.clear(); - calo.hwPt = pt(in) * l1ct::pt_t(0.5); // the LSB for GCT objects - calo.hwEta = l1ct::Scales::makeGlbEta(eta(in) * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) - calo.hwPhi = l1ct::Scales::makePhi(phi(in) * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame + calo.hwPt = inclus.pt() * inclus.ptLSB(); // the LSB for GCT objects + calo.hwEta = l1ct::Scales::makeGlbEta(inclus.eta() * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) + calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame // need to add EmPt when it becomes available - calo.hwEmPt = ecal(in) * l1ct::pt_t(0.5); + calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); // need to add emid, default to zero for had/PF clusters from GCT calo.hwEmID = 0; diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index e521d6f6d2272..dbf2b48dd92c9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -23,7 +23,6 @@ if args.patternFilesOFF: print(f'Switching off pattern file creation: patternFilesOFF is {args.patternFilesOFF}') - import FWCore.ParameterSet.Config as cms from Configuration.StandardSequences.Eras import eras @@ -33,27 +32,31 @@ process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") process.load("FWCore.MessageLogger.MessageLogger_cfi") process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), allowUnscheduled = cms.untracked.bool(False) ) -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1008)) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1)) process.MessageLogger.cerr.FwkReport.reportEvery = 1 -# process.MessageLogger.cerr.threshold = "DEBUG" -# process.MessageLogger.debugModules = ["l1tLayer1BarrelTDR"] process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring('file:inputs110X.root'), + fileNames = cms.untracked.vstring('file:inputs140X_1.root', + ), inputCommands = cms.untracked.vstring("keep *", "drop l1tPFClusters_*_*_*", "drop l1tPFTracks_*_*_*", "drop l1tPFCandidates_*_*_*", - "drop l1tTkPrimaryVertexs_*_*_*", - "drop l1tKMTFTracks_*_*_*"), - skipEvents = cms.untracked.uint32(0), + "drop l1tTkPrimaryVertexs_*_*_*") ) process.load('Configuration.Geometry.GeometryExtendedRun4D110Reco_cff') process.load('Configuration.Geometry.GeometryExtendedRun4D110_cff') process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs +process.load('SimCalorimetry.HGCalSimProducers.hgcalDigitizer_cfi') # needed for HGCAL_noise_fC process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +process.load('RecoMET.Configuration.GenMETParticles_cff') +process.load('RecoMET.METProducers.genMetTrue_cfi') + +from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets +from RecoMET.METProducers.pfMet_cfi import pfMet from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, '141X_mcRun4_realistic_v3', '') @@ -70,47 +73,54 @@ process.l1tSAMuonsGmt = l1tSAMuonsGmt.clone() from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import l1tPhase2L1CaloEGammaEmulator process.l1tPhase2L1CaloEGammaEmulator = l1tPhase2L1CaloEGammaEmulator.clone() + from L1Trigger.L1CaloTrigger.l1tPhase2CaloPFClusterEmulator_cfi import l1tPhase2CaloPFClusterEmulator process.l1tPhase2CaloPFClusterEmulator = l1tPhase2CaloPFClusterEmulator.clone() -# from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator -# process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() + +from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator +process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() + +from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cff import l1tNNTauProducerPuppi +process.l1tNNTauProducerPuppi = l1tNNTauProducerPuppi.clone() + +from L1Trigger.Phase2L1ParticleFlow.l1tMETPFProducer_cfi import l1tMETPFProducer +process.l1tMETPFProducer = l1tMETPFProducer.clone() from L1Trigger.L1CaloTrigger.l1tPhase2CaloToCorrelatorTMI18_cfi import l1tPhase2CaloToCorrelatorTMI18 process.l1tPhase2CaloToCorrelatorTMI18 = l1tPhase2CaloToCorrelatorTMI18.clone() process.L1TInputTask = cms.Task( - process.l1tSAMuonsGmt, - process.l1tPhase2L1CaloEGammaEmulator, - process.l1tPhase2CaloPFClusterEmulator, - process.l1tPhase2CaloToCorrelatorTMI18 + process.l1tPhase2L1CaloEGammaEmulator, + process.l1tPhase2CaloPFClusterEmulator, + process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator, + process.l1tPhase2CaloToCorrelatorTMI18, + process.l1tSAMuonsGmt, + process.l1tGTTInputProducer, + process.l1tTrackSelectionProducer, + process.l1tVertexFinderEmulator, + # process.l1tLayer1Barrel, + # process.l1tLayer1HGCal, + # process.l1tLayer1HGCalNoTK, + process.L1TLayer1TaskInputsTask, + # process.L1TLayer1Task, + process.L1TLayer2EGTask, + process.l1tMETPFProducer) + +process.centralGen = cms.EDFilter("CandPtrSelector", src = cms.InputTag("genParticlesForMETAllVisible"), cut = cms.string("abs(eta) < 2.4")) +process.barrelGen = cms.EDFilter("CandPtrSelector", src = cms.InputTag("genParticlesForMETAllVisible"), cut = cms.string("abs(eta) < 1.5")) +process.genMetCentralTrue = process.genMetTrue.clone(src = cms.InputTag("centralGen")) +process.L1TInputTask.add( + process.genParticlesForMETAllVisible, + process.centralGen, + process.barrelGen, + process.genMetCentralTrue ) +#### ntuple producer -- TO BE REMOVED +process.load('L1Trigger.L1CaloPhase2Analyzer.l1TCaloAnalyzer_cfi') +process.TFileService = cms.Service("TFileService", fileName = cms.string("perfTuple.root")) -from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter -l1ctLayer2SCJetsProducts = cms.VPSet([cms.PSet(jets = cms.InputTag("l1tSC4PFL1PuppiCorrectedEmulator"), - nJets = cms.uint32(12), - mht = cms.InputTag("l1tSC4PFL1PuppiCorrectedEmulatorMHT"), - nSums = cms.uint32(2), - jetEncoding = cms.string("GT")), - cms.PSet(jets = cms.InputTag("l1tSC8PFL1PuppiCorrectedEmulator"), - nJets = cms.uint32(12), - jetEncoding = cms.string("GTWide")) - ]) -process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(collections = l1ctLayer2SCJetsProducts) - -l1ctLayer2SC4NGJetsProducts = cms.VPSet([cms.PSet(jets = cms.InputTag("l1tSC4NGJetProducer","l1tSC4NGJets"), - nJets = cms.uint32(12), - mht = cms.InputTag("l1tNGMHTPFProducer"), - nSums = cms.uint32(2), - jetEncoding = cms.string("GT")), - cms.PSet(jets = cms.InputTag("l1tSC8PFL1PuppiCorrectedEmulator"), - nJets = cms.uint32(12), - jetEncoding = cms.string("GTWide")) - ]) -process.l1tLayer2SeedConeNGJetWriter = l1tSeededConeJetFileWriter.clone(collections = l1ctLayer2SC4NGJetsProducts, - outputFilename = 'L1CTSCNGJetsPatterns') - - +## Realistic barrel emulation process.l1tLayer1BarrelTDR = process.l1tLayer1Barrel.clone() process.l1tLayer1BarrelTDR.regionizerAlgo = cms.string("TDR") process.l1tLayer1BarrelTDR.regionizerAlgoParameters = cms.PSet( @@ -119,7 +129,7 @@ nEmCalo = cms.uint32(12), nMu = cms.uint32(2), debug = cms.untracked.bool(True), - debug_mu = cms.untracked.bool(True) + debug_emcalo = cms.untracked.bool(True) ) process.l1tLayer1BarrelTDR.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelTDR.pfAlgoParameters.nSelCalo = 15 @@ -132,17 +142,6 @@ process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nTRACK_EGIN = 22 process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nEMCALO_EGIN = 12 -process.l1tLayer1BarrelTDR.hadClusters = cms.InputTag('l1tPhase2GCTBarrelToCorrelatorLayer1Emulator', 'GCTHadDigiClusters') -process.l1tLayer1BarrelTDR.gctHadInputConversionAlgo = cms.string("Emulator") - -process.l1tLayer1BarrelTDR.caloSectors = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 1.5), - phiSlices = cms.uint32(3), - phiZero = cms.double(math.pi/18) - ) -) - process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() process.l1tLayer1BarrelSerenity.regionizerAlgo = "MiddleBufferMultififo" process.l1tLayer1BarrelSerenity.regionizerAlgoParameters = cms.PSet( From 6db9a052b9971fed4240bca4904c5008fc30c7b4 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 25 Feb 2026 09:59:12 -0600 Subject: [PATCH 32/92] re-enable most of the algorithms, remove extra printouts --- .../tdr_alt_regionizer_elements_ref.icc | 7 ---- .../plugins/L1TCorrelatorLayer1Producer.cc | 34 +---------------- .../test/make_l1ct_binaryFiles_cfg.py | 38 +++++++++++++------ 3 files changed, 29 insertions(+), 50 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index 36ab3284bc04b..47d371884441b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -246,13 +246,6 @@ void l1ct::tdr_alt_regionizer::Regionizer::setBuffers(const std::vector { void addHGCalHadCalo(const l1t::HGCalMulticluster &calo, const edm::Ptr &caloPtr); // GCT input clusters void addGCTHadCalo(const l1t::PFCluster &calo, const edm::Ptr &caloPtr); - // for GCT raw calos as input (FIXME) + // for GCT raw calos as input void addGCTCaloRaw(const l1tp2::GCTDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); - //void addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, unsigned int linkidx, unsigned int entidx); // add objects in already-decoded format void addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t); void addDecodedMuon(l1ct::DetectorSector &sec, const l1t::SAMuon &t); @@ -864,8 +863,6 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet event_.raw.hgcalcluster.clear(); event_.raw.gctcluster.clear(); - std::cout << "Call to initSectorsAndRegions, " << iConfig.getParameter("regionizerAlgo") << std::endl; - for (const edm::ParameterSet &preg : iConfig.getParameter("caloSectors")) { std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) @@ -881,7 +878,6 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { float phiCenter = reco::reducePhiRange(iphi * phiWidth + phiZero); - std::cout << "calo sector eta " << etaBoundaries[ieta] << " to " << etaBoundaries[ieta + 1] << ", phi " << phiCenter * 720 / M_PI << std::endl; event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); @@ -905,7 +901,6 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { float phiCenter = reco::reducePhiRange(iphi * phiWidth + phiZero); - std::cout << "raw calo sector eta " << etaBoundaries[ieta] << " to " << etaBoundaries[ieta + 1] << ", phi " << phiCenter * 720 / M_PI << std::endl; event_.raw.gctcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); } } @@ -1047,53 +1042,32 @@ unsigned int L1TCorrelatorLayer1Producer::hadDecodedIndex(unsigned int linkidx, return 2*linkidx + 1; } } + void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTDigiClusterLink &link, unsigned int linkidx, unsigned int entidx) { if (auto p = std::get_if(&link[entidx])) { - std::cout << "GCT Raw em link " << linkidx << ", entry " << entidx << " data " - << std::hex << p->data() << std::dec << std::endl; // (For EM don't currently suport ideal, so it is always Emulated) event_.raw.gctcluster[linkidx].obj.push_back(p->data()); if (p->pt() > 0) { auto decidx = emDecodedIndex(linkidx, entidx); - std::cout << " adding to decoded index " << decidx << std::endl; addDecodedGCTEmCalo(event_.decoded.emcalo[decidx], *p); } } else if (auto p = std::get_if(& link[entidx])) { - std::cout << "GCT Raw had link " << linkidx << ", entry " << entidx << " data " - << std::hex << p->data() << std::dec << std::endl; // Only do this if using Emulated GCT input, not Ideal. if (hadGCTCands_.isUninitialized()) { event_.raw.gctcluster[linkidx].obj.push_back(p->data()); if (p->pt() > 0) { auto decidx = hadDecodedIndex(linkidx, entidx); - std::cout << " adding to decoded index " << decidx << std::endl; addDecodedGCTHadCalo(event_.decoded.hadcalo[decidx], *p); } } } else { // this is the extra data that is neither had nor em - std::cout << "GCT Raw null link " << linkidx << ", entry " << entidx << std::endl; - if (entidx == 1) { - auto val = std::get(link.at(entidx)); - std::cout << " The emcalo value is " << val.data() << std::endl; - } event_.raw.gctcluster[linkidx].obj.push_back(0); // the value should not be used } } -// void L1TCorrelatorLayer1Producer::addGCTHadCaloRaw(const l1tp2::GCTHadDigiClusterLink &link, -// unsigned int linkidx, -// unsigned int entidx) { -// // in the "Ideal" regionizer, ignore the second set that is sent; only use the first -// auto caloIdx = calomapping[linkidx]; -// if (caloIdx < event_.raw.gctHad.size()) { -// event_.raw.gctHad[caloIdx].obj.push_back(link[entidx].data()); -// addDecodedGCTHadCalo(event_.decoded.hadcalo[caloIdx], link[entidx]); -// } -// } - void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t) { std::pair tkAndSel; if (trackInput_) { @@ -1153,10 +1127,7 @@ void L1TCorrelatorLayer1Producer::addDecodedGCTEmCalo(l1ct::DetectorSectordecode(sec.region, digi.data()); - std::cout << "emclus decode " << std::hex << digi.data() << std::dec << " to pt = " << calo.hwPt << std::endl; - auto caloPtr = edm::refToPtr(digi.clusterRef()); - // FIXME: should check hwPt > 0 addDecodedEmCalo(calo, caloPtr, sec); } @@ -1165,7 +1136,6 @@ void L1TCorrelatorLayer1Producer::addDecodedGCTHadCalo(l1ct::DetectorSectordecode(sec.region, digi.data()); auto caloPtr = edm::refToPtr(digi.clusterRef()); - // FIXME: should check hwPt > 0 addDecodedHadCalo(calo, caloPtr, sec); } diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index dbf2b48dd92c9..4f59b330e4dbb 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -1,6 +1,5 @@ import argparse import sys -import math # example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py --patternFilesOFF # example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py --dumpFilesOFF --serenity @@ -32,7 +31,7 @@ process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") process.load("FWCore.MessageLogger.MessageLogger_cfi") process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), allowUnscheduled = cms.untracked.bool(False) ) -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1)) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1008)) process.MessageLogger.cerr.FwkReport.reportEvery = 1 process.source = cms.Source("PoolSource", @@ -98,11 +97,7 @@ process.l1tGTTInputProducer, process.l1tTrackSelectionProducer, process.l1tVertexFinderEmulator, - # process.l1tLayer1Barrel, - # process.l1tLayer1HGCal, - # process.l1tLayer1HGCalNoTK, process.L1TLayer1TaskInputsTask, - # process.L1TLayer1Task, process.L1TLayer2EGTask, process.l1tMETPFProducer) @@ -116,9 +111,30 @@ process.genMetCentralTrue ) -#### ntuple producer -- TO BE REMOVED -process.load('L1Trigger.L1CaloPhase2Analyzer.l1TCaloAnalyzer_cfi') -process.TFileService = cms.Service("TFileService", fileName = cms.string("perfTuple.root")) +from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter +l1ctLayer2SCJetsProducts = cms.VPSet([cms.PSet(jets = cms.InputTag("l1tSC4PFL1PuppiCorrectedEmulator"), + nJets = cms.uint32(12), + mht = cms.InputTag("l1tSC4PFL1PuppiCorrectedEmulatorMHT"), + nSums = cms.uint32(2), + jetEncoding = cms.string("GT")), + cms.PSet(jets = cms.InputTag("l1tSC8PFL1PuppiCorrectedEmulator"), + nJets = cms.uint32(12), + jetEncoding = cms.string("GTWide")) + ]) +process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(collections = l1ctLayer2SCJetsProducts) + +l1ctLayer2SC4NGJetsProducts = cms.VPSet([cms.PSet(jets = cms.InputTag("l1tSC4NGJetProducer","l1tSC4NGJets"), + nJets = cms.uint32(12), + mht = cms.InputTag("l1tNGMHTPFProducer"), + nSums = cms.uint32(2), + jetEncoding = cms.string("GT")), + cms.PSet(jets = cms.InputTag("l1tSC8PFL1PuppiCorrectedEmulator"), + nJets = cms.uint32(12), + jetEncoding = cms.string("GTWide")) + ]) +process.l1tLayer2SeedConeNGJetWriter = l1tSeededConeJetFileWriter.clone(collections = l1ctLayer2SC4NGJetsProducts, + outputFilename = 'L1CTSCNGJetsPatterns') + ## Realistic barrel emulation process.l1tLayer1BarrelTDR = process.l1tLayer1Barrel.clone() @@ -128,8 +144,8 @@ nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), nMu = cms.uint32(2), - debug = cms.untracked.bool(True), - debug_emcalo = cms.untracked.bool(True) + debug = cms.untracked.bool(False), + debug_emcalo = cms.untracked.bool(False) ) process.l1tLayer1BarrelTDR.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelTDR.pfAlgoParameters.nSelCalo = 15 From 1f38f803cafc8d6ed920856b19923b2ad06c2d99 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 25 Feb 2026 17:31:54 -0600 Subject: [PATCH 33/92] fix tracker pattern file order configuration, extra debugging printouts --- .../tdr_alt_regionizer_elements_ref.h | 2 +- .../tdr_alt_regionizer_elements_ref.icc | 21 ++++++++++--------- .../python/l1ctLayer1_patternWriters_cff.py | 5 ++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h index aa043de8fed21..d9d493af2c850 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -64,7 +64,7 @@ namespace l1ct { void reset() { data_.clear(); } - void printDebug(size_t bufIdx) const; + void printDebug(size_t bufIdx, size_t logBufIdx) const; private: diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index 47d371884441b..cc49b68914f32 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -44,10 +44,10 @@ unsigned int l1ct::tdr_alt_regionizer::Buffer::numEntries() const { } template -void l1ct::tdr_alt_regionizer::Buffer::printDebug(size_t bufferIdx) const { +void l1ct::tdr_alt_regionizer::Buffer::printDebug(size_t bufferIdx, size_t logBufIdx) const { for (auto srq_it = data_.rbegin(); srq_it != data_.rend(); ++srq_it) { for (unsigned int j = 0; j < srq_it->second.size(); j++) { - dbgCout() << "\t" << bufferIdx << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() + dbgCout() << logBufIdx << "\t" << bufferIdx << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() << std::endl; } dbgCout() << "-------------------------------" << std::endl; @@ -416,19 +416,20 @@ void l1ct::tdr_alt_regionizer::Regionizer::clearSmallRegions() { template void l1ct::tdr_alt_regionizer::Regionizer::printDebug(int count) const { dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl; - dbgCout() << count << "\tbuffer\tregion\titem\tpt\teta\tphi\t" << std::endl; - for (auto sector : sectorMapLogToPhys_) { - buffers_[sector].printDebug(sector); + dbgCout() << count << "\tbuffer\tphysreg\titem\tpt\teta\tphi\t" << std::endl; + for (size_t logSector = 0; logSector < sectorMapLogToPhys_.size(); logSector++) { + auto physSector = sectorMapLogToPhys_[logSector]; + buffers_[physSector].printDebug(physSector, logSector); } dbgCout() << "SMALL REGIONS" << std::endl; for (unsigned int region = 0; region < regionmap_.size(); region++) { - dbgCout() << count << "\tregion\t\titem\tpt\tloceta\tlocphi" << std::endl; - auto realRegIdx = regionIndex(region); - auto etaC = regions_[realRegIdx].intEtaCenter(); - auto phiC = regions_[realRegIdx].intPhiCenter(); + dbgCout() << count << "\tregion\t\tphysRegion\titem\tpt\tloceta\tlocphi" << std::endl; + auto physRegIdx = regionIndex(region); + auto etaC = regions_[physRegIdx].intEtaCenter(); + auto phiC = regions_[physRegIdx].intPhiCenter(); for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) { - dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" + dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" << physRegIdx << "\t" << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t" << smallRegionObjects_[region][j].intPhi() << std::endl; } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index cf00e5580a3be..5baad18dd265f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -249,13 +249,16 @@ debugFileName = cms.string("l1BarrelApx-pfout") ) +# For the tracker, the logical (firmware) fiber order sorts negative eta first, then positive, +# and in a given eta from most negative to most positive phi. That is reflected in this remapping +trackFiberOrder = (4, 5, 6, 7, 8, 0, 1, 2, 3, 13, 14, 15, 16, 17, 9, 10, 11, 12) # phys to logical # This includes the tracker, GCT, muon and GTT sector mapping. There is only one GTT fiber, with a logical firmware link of 123. barrelApxWriterConfig = _barrelWriterOutputOnly.clone( fileFormat = cms.string("APx"), gttLink = cms.int32(123), gmtLink = cms.int32(21), gctSectors = cms.VPSet(*[cms.PSet(gctLink = cms.int32(i)) for i in (18, 19, 20)]), - tfSectors = cms.VPSet(*[cms.PSet(tfLink = cms.int32(i)) for i in range(18)]), + tfSectors = cms.VPSet(*[cms.PSet(tfLink = cms.int32(i)) for i in trackFiberOrder]), inputFileName = cms.string("l1BarrelApx-inputs") ) From 992cc9ac6580e2a4687c7e4ba8ee0668f60fb79c Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 26 Feb 2026 10:07:34 -0600 Subject: [PATCH 34/92] make calo_links function a member function --- .../interface/regionizer/tdr_alt_regionizer_elements_ref.h | 1 + .../regionizer/tdr_alt_regionizer_elements_ref.icc | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h index d9d493af2c850..f80bbf30ab491 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h @@ -108,6 +108,7 @@ namespace l1ct { /// logical links associated with a logical sr (customized for each type) std::vector linksForSR(size_t sr) const; + std::vector caloLinksHelper(size_t iphi) const; unsigned int numBuffers() const { return buffers_.size(); } unsigned int numEntries(unsigned int bufferIndex) const { return buffers_[bufferIndex].numEntries(); } diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc index cc49b68914f32..da75952db66be 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc @@ -317,7 +317,8 @@ inline std::vector l1ct::tdr_alt_regionizer::Regionizer: } // slighlty more complicated because of logical index; -std::vector calo_links(size_t iphi) { +template +inline std::vector l1ct::tdr_alt_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { if (iphi < 2) { std::vector retval = {11, 5, 6, 0, 7, 1, 8, 2}; return retval; @@ -342,13 +343,13 @@ std::vector calo_links(size_t iphi) { template <> inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { const std::pair logic_sr = get_small_region(sr); - return calo_links(logic_sr.second); + return caloLinksHelper(logic_sr.second); } template <> inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { const std::pair logic_sr = get_small_region(sr); - return calo_links(logic_sr.second); + return caloLinksHelper(logic_sr.second); } template <> From eb7bb3332891734bb0ec79a419b056848090b063 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 26 Feb 2026 10:49:14 -0600 Subject: [PATCH 35/92] Change all the tdr_alt back to tdr. --- .../interface/GCTEmDigiCluster.h | 1 - .../interface/l1-converters/gcteminput_ref.h | 1 - .../interface/l1-converters/gcthadinput_ref.h | 1 - .../tdr_alt_regionizer_elements_ref.h | 173 ----- .../tdr_alt_regionizer_elements_ref.icc | 475 ------------ .../regionizer/tdr_alt_regionizer_ref.h | 52 -- .../regionizer/tdr_regionizer_elements_ref.h | 248 +------ .../tdr_regionizer_elements_ref.icc | 678 ++++++------------ .../interface/regionizer/tdr_regionizer_ref.h | 31 +- .../plugins/L1TCorrelatorLayer1Producer.cc | 28 +- .../L1TCorrelatorLayer1PatternFileWriter.cc | 6 +- .../src/l1-converters/gcthadinput_ref.cpp | 2 +- .../src/regionizer/tdr_alt_regionizer_ref.cpp | 124 ---- .../src/regionizer/tdr_regionizer_ref.cpp | 140 ++-- 14 files changed, 348 insertions(+), 1612 deletions(-) delete mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h delete mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc delete mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h delete mode 100644 L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h index 6575409031eba..b9949e1951fc3 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -19,7 +19,6 @@ namespace l1tp2 { // Constants static constexpr float LSB_PT = 0.5; // 0.5 GeV - #ifdef CMSSW_GIT_HASH // Reference to the original float cluster edm::Ref clusterRef_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h index 6638e60f2846e..646b996e0f1e9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcteminput_ref.h @@ -35,7 +35,6 @@ namespace l1ct { l1ct::EmCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; private: - // tools for GCT clusters l1tpf::corrector corrector_; l1tpf::ParametricResolution resol_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h index 6b8cc3b1b20a6..a43a60fa5e107 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h @@ -21,7 +21,6 @@ namespace l1ct { static edm::ParameterSetDescription getParameterSetDescription(); l1ct::HadCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; - }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h deleted file mode 100644 index f80bbf30ab491..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef tdr_alt_regionizer_elements_ref_h -#define tdr_alt_regionizer_elements_ref_h - -#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" - -#include -#include -#include -#include -#include - -#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" - -namespace l1ct { - namespace tdr_alt_regionizer { - - inline int phi_wrap(int local_phi) { - if (local_phi > l1ct::Scales::INTPHI_PI) - local_phi -= l1ct::Scales::INTPHI_TWOPI; - else if (local_phi <= -l1ct::Scales::INTPHI_PI) - local_phi += l1ct::Scales::INTPHI_TWOPI; - return local_phi; - } - - - /// the components that make up the L1 regionizer buffer - template - class BufferEntry { - public: - BufferEntry() {} - BufferEntry(const T& obj, int glbeta, int glbphi); - - int pt() const { return obj_.intPt(); } - int glbPhi() const { return glbphi_; } - int glbEta() const { return glbeta_; } - - //T obj() { return obj_; } - const T& obj() const { return obj_; } - - private: - T obj_; - /// the SR linearized indices (can index regionmap_) where this object needs to go - int glbeta_, glbphi_; - }; - - /// The L1 regionizer buffer (corresponding to level1_fifo_buffer.vhd) - template - class Buffer { - public: - Buffer() {} - - void addEntry(const T& obj, - std::vector srs, // LOGICAL SRs - int glbeta, - int glbphi); - - bool empty(size_t sr) const; - BufferEntry getEntry(size_t sr); - - // mainly for debug/validation, to check that nothing is left over after an event - // This is the number of entries in all the deques, not necessarily the number of - // entries in the map. - unsigned int numEntries() const; - - void reset() { data_.clear(); } - - void printDebug(size_t bufIdx, size_t logBufIdx) const; - - private: - - /// The actual data, indexed by the physical SR - std::map>> data_; - - }; - - template - class Regionizer { - public: - Regionizer() = delete; - Regionizer(unsigned int maxobjects, - bool debug = false); - - void initSectors(const std::vector>& sectors); - void initSectors(const DetectorSector& sector); - void initRegions(const std::vector& regions); - - void fillBuffers(const std::vector>& sectors); - void fillBuffers(const DetectorSector& sector); - - void run(); - - void reset(); - - const std::vector>& smallRegions() const { return smallRegionObjects_; } - void clearSmallRegions(); - - void printDebug(int count) const; - - private: - - const size_t SMALL_REGION_ETA_COUNT = 6; - const size_t SMALL_REGION_PHI_COUNT = 9; - - /// @brief convert to logical SR - /// @param sr linear small region - /// @return pair (eta, phi) region index) - std::pair get_small_region(size_t sr) const; - - /// logical links associated with a logical sr (customized for each type) - std::vector linksForSR(size_t sr) const; - std::vector caloLinksHelper(size_t iphi) const; - - unsigned int numBuffers() const { return buffers_.size(); } - unsigned int numEntries(unsigned int bufferIndex) const { return buffers_[bufferIndex].numEntries(); } - - std::vector getSmallRegions(int glbeta, int glbphi) const; - - /// fill the buffers with an event's link data. The buffers should be empty--checked by assert - void setBuffers(const std::vector>&& objvecvec); - - /// 'put' object in small region. The sr is physics - void addToSmallRegion(size_t sr, BufferEntry&& bufEntry); - - /// returns 2D arrays, sectors (links) first dimension, objects second - std::vector> fillLinks(const std::vector>& sectors) const; - std::vector> fillLinks(const DetectorSector& sector) const; - - // this function is for sorting small regions first in phi and then in eta. - // It takes regions_ indices - bool sortRegionsRegular(size_t a, size_t b) const; - bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; - - // This is for sorting sectors. It sorts in eta first, then phi - bool sortSectors(size_t a, size_t b) const; - bool sortSectorsHelper(int etaa, int etab, int phia, int phib) const; - - /// get the index in regions_ for a particular SR. - size_t regionIndex(int sr) const { return regionmap_.at(sr); } - - /// get the logical buffer index (i.e. the index in the order in the firmware) - size_t logicBuffIndex(size_t bufIdx) const; - - /// The maximum number of objects to output per small region - unsigned int maxobjects_; - - /// the region information associated with each input sector (link). Note, this is indexed in physical order - std::vector sectors_; - - /// the region information associated with each SR - std::vector regions_; - - /// indices of regions that are in the big region (board) - std::vector regionmap_; - - /// indices maps the sectors from the way they appear in the software to the (logical) order they are done in the regionizer firmware - std::vector sectorMapPhysToLog_; - - /// the inverse mapping of sectormap_ (only used for debug printing) - std::vector sectorMapLogToPhys_; - - /// The buffers. There is one buffer per link (or sector). Note, this is also indexed in physical order (= same index as sectors) - std::vector> buffers_; - - /// The objects in each small region handled in board; Indexing corresponds to that in regionmap_ - std::vector> smallRegionObjects_; - - bool debug_; - }; - - } // namespace tdr_regionizer -} // namespace l1ct - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc deleted file mode 100644 index da75952db66be..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc +++ /dev/null @@ -1,475 +0,0 @@ -#include - -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - -// BUFFER ENTRY AND BUFFER -template -l1ct::tdr_alt_regionizer::BufferEntry::BufferEntry( - const T& obj, int glbeta, int glbphi) - : obj_(obj), glbeta_(glbeta), glbphi_(glbphi) {} - -template -inline void l1ct::tdr_alt_regionizer::Buffer::addEntry(const T& obj, std::vector srIndices, - int glbeta, int glbphi) { - for (auto sr : srIndices) { - data_[sr].emplace_back(obj, glbeta, glbphi); // note, this creates a deque if needed - } -} - -template -inline bool l1ct::tdr_alt_regionizer::Buffer::empty(size_t sr) const { - auto it = data_.find(sr); - if (it != data_.end()) { - return it->second.empty(); - } else { - return true; - } -} - -template -inline l1ct::tdr_alt_regionizer::BufferEntry l1ct::tdr_alt_regionizer::Buffer::getEntry(size_t sr) { - BufferEntry entry = data_[sr].front(); - data_[sr].pop_front(); - return entry; -} - -template -unsigned int l1ct::tdr_alt_regionizer::Buffer::numEntries() const { - unsigned int count = 0; - for (const auto& [key, value] : data_) { - count += value.size(); - } - return count; -} - -template -void l1ct::tdr_alt_regionizer::Buffer::printDebug(size_t bufferIdx, size_t logBufIdx) const { - for (auto srq_it = data_.rbegin(); srq_it != data_.rend(); ++srq_it) { - for (unsigned int j = 0; j < srq_it->second.size(); j++) { - dbgCout() << logBufIdx << "\t" << bufferIdx << "\t" << srq_it->first << "\t" << j << "\t" << srq_it->second[j].pt() - << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() << std::endl; - } - dbgCout() << "-------------------------------" << std::endl; - } -} - -// REGIONIZER -template -l1ct::tdr_alt_regionizer::Regionizer::Regionizer(unsigned int maxobjects, - bool debug) - : maxobjects_(maxobjects), debug_(debug) {} - -template -void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const std::vector>& sectors) { - - // we need a mapping of physical (what's in the sectors variable) to logical, - // but it's easier to create the inverse, first - - if (debug_) { - dbgCout() << "sectors.size() = " << sectors.size() << std::endl; - } - - for (const auto& sector : sectors) { - if (debug_) { - dbgCout() << "intEtaCenter() = " << sector.region.intEtaCenter() - << ", intPhiCenter() = " << sector.region.intPhiCenter() << std::endl; - } - sectorMapLogToPhys_.push_back(sectors_.size()); // currently set to 0, 1, 2, ... - sectors_.push_back(sector.region); - } - - buffers_.resize(sectors_.size()); - - std::sort(sectorMapLogToPhys_.begin(), sectorMapLogToPhys_.end(), [this](size_t a, size_t b) { - return this->sortSectors(a, b); - }); - // now logical to physical mapping should be correct - - if (debug_) { - for (auto val : sectorMapLogToPhys_) { - dbgCout() << "sectorMapLogToPhys phys index = " << val << ", eta = " << sectors_[val].intEtaCenter() - << ", phi = " << sectors_[val].intPhiCenter() << std::endl; - } - } - - // now invert the sectorMapLogToPhys_ - sectorMapPhysToLog_.resize(sectorMapLogToPhys_.size()); - for (size_t i = 0; i < sectorMapLogToPhys_.size(); ++i) { - sectorMapPhysToLog_[sectorMapLogToPhys_[i]] = i; - } -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::initSectors(const DetectorSector& sector) { - sectors_.push_back(sector.region); - sectorMapLogToPhys_.push_back(0); - sectorMapPhysToLog_.push_back(0); - buffers_.resize(1); - if (debug_) { - dbgCout() << "Number of sectors: " << sectors_.size() << std::endl; - } -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::fillBuffers(const std::vector>& sectors) { - setBuffers(fillLinks(sectors)); -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::fillBuffers(const DetectorSector& sector) { - setBuffers(fillLinks(sector)); -} - -// this function is for sorting small regions; For consistency with new regionizer, swap order. -// New order: in phi first, then in eta -template -bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsRegular(size_t a, size_t b) const { - auto etaa = regions_[a].intEtaCenter(); - auto etab = regions_[b].intEtaCenter(); - auto phia = regions_[a].intPhiCenter(); - auto phib = regions_[b].intPhiCenter(); - return sortRegionsHelper(etaa, etab, phia, phib); -} - -// this function is for sorting small regions -// in phi first, then in eta -template -bool l1ct::tdr_alt_regionizer::Regionizer::sortRegionsHelper(int etaa, int etab, int phia, int phib) const { - // first do phi - if (phia < phib) { - return true; - } else if (phia > phib) { - return false; - } - - // Only here if have same phi - if (etaa < etab) { - return true; - } else { - return false; - } -} - -// this function is for sorting Sectors (mainly tracker) -// note it is opposite of regions to keep consistent -// It sorts in eta first, then phi -template -bool l1ct::tdr_alt_regionizer::Regionizer::sortSectorsHelper(int etaa, int etab, int phia, int phib) const { - // first do eta - if (etaa < etab) { - return true; - } else if (etaa > etab) { - return false; - } - - // Only here if have same eta - if (phia < phib) { - return true; - } else { - return false; - } -} - -// this function is for sorting the sectors -// in eta first, then in phi -template -bool l1ct::tdr_alt_regionizer::Regionizer::sortSectors(size_t a, size_t b) const { - // first do eta - auto etaa = sectors_[a].intEtaCenter(); - auto etab = sectors_[b].intEtaCenter(); - auto phia = sectors_[a].intPhiCenter(); - auto phib = sectors_[b].intPhiCenter(); - return sortSectorsHelper(etaa, etab, phia, phib); -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::initRegions(const std::vector& regions) { - regions_.resize(regions.size()); - smallRegionObjects_.resize(regions.size()); - for (unsigned int i = 0; i < regions.size(); ++i) { - regions_[i] = regions[i].region; - regionmap_.push_back(i); - if (debug_) { - dbgCout() << "region [" << i << "] eta/phi: " << regions_[i].intEtaCenter() << " " << regions_[i].intPhiCenter() - << ", eta half width = " << regions_[i].hwEtaHalfWidth.to_int() - << ", phi half width = " << regions_[i].hwPhiHalfWidth.to_int() - << ", eta extra = " << regions_[i].hwEtaExtra.to_int() - << ", phi extra = " << regions_[i].hwPhiExtra.to_int() << std::endl; - } - } - std::sort( - regionmap_.begin(), regionmap_.end(), [this](size_t a, size_t b) { return this->sortRegionsRegular(a, b); }); - - if (debug_) { - for (auto val : regionmap_) { - dbgCout() << "regionmap_ phys index = " << val << ", eta = " << regions_[val].intEtaCenter() - << ", phi = " << regions_[val].intPhiCenter() << std::endl; - } - } - -} - - -template -std::vector l1ct::tdr_alt_regionizer::Regionizer::getSmallRegions(int glbeta, int glbphi) const { - std::vector srIndices; // the signal regions this object should go into - - // only iterate over regions covered by board - for (size_t i = 0; i < regionmap_.size(); i++) { - auto regionidx = regionIndex(i); - int regphi = phi_wrap(glbphi - regions_[regionidx].intPhiCenter()); - int regeta = glbeta - regions_[regionidx].intEtaCenter(); - - // add a special check to not have 3 eta regions - if (regions_[regionidx].isInside(regeta, regphi) && - !((glbeta == 57 && regeta == -115) || (glbeta == -57 && regeta == 115))) { - srIndices.push_back(i); - } - } - - return srIndices; -} - - -template -void l1ct::tdr_alt_regionizer::Regionizer::setBuffers(const std::vector>&& objvecvec) { - assert(numBuffers() == objvecvec.size()); - for (unsigned int buffer = 0; buffer < numBuffers(); buffer++) { - assert(buffers_[buffer].numEntries() == 0); // should be empty - for (auto& obj : objvecvec[buffer]) { - auto glbphi = sectors_[buffer].hwGlbPhiOf(obj).to_int(); - auto glbeta = sectors_[buffer].hwGlbEtaOf(obj).to_int(); - if (debug_) { - dbgCout() << "Buffer " << buffer << ": add obj with pt = " << obj.intPt() - << ", glb eta = " << glbeta << ". glb phi = " << glbphi << std::endl; - } - // get the SR indices that this object should go into - auto srs = getSmallRegions(glbeta, glbphi); - buffers_[buffer].addEntry(obj, - srs, - glbeta, - glbphi); - } - } -} - -// sr is physical -template -void l1ct::tdr_alt_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntry&& bufEntry) { - auto rawObj = bufEntry.obj(); - - // in small region, the relative eta and phi are based on a different center, so need to update - auto etaC = regions_[sr].intEtaCenter(); - auto phiC = regions_[sr].intPhiCenter(); - - int locEta = bufEntry.glbEta() - etaC; - int locPhi = phi_wrap(bufEntry.glbPhi() - phiC); - - rawObj.hwEta = locEta; - rawObj.hwPhi = locPhi; - - smallRegionObjects_[sr].push_back(rawObj); -} - -// This is a dummy, should never be used. -template -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t) const { - std::vector retval; - throw cms::Exception("LogicError") << "This should be customized per type."; - return retval; -} - -template <> -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { - std::pair logic_sr = get_small_region(sr); - const auto& ieta = logic_sr.first; - const auto& iphi = logic_sr.second; - std::vector retval; - if (ieta < 3) { - auto nom = iphi; - auto smaller = (nom == 0) ? 8 : nom - 1; - auto bigger = (nom == 8) ? 0 : nom + 1; - retval.push_back(nom); - retval.push_back(smaller); - retval.push_back(bigger); - if (ieta == 2) { - // also add the other ones - retval.push_back(nom + 9); - retval.push_back(smaller + 9); - retval.push_back(bigger + 9); - } - } else { - auto nom = iphi + 9; - auto smaller = (nom == 9) ? 17 : nom - 1; - auto bigger = (nom == 17) ? 9 : nom + 1; - retval.push_back(nom); - retval.push_back(smaller); - retval.push_back(bigger); - if (ieta == 3) { - // also add the other ones - retval.push_back(nom - 9); - retval.push_back(smaller - 9); - retval.push_back(bigger - 9); - } - } - return retval; -} - -// slighlty more complicated because of logical index; -template -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { - if (iphi < 2) { - std::vector retval = {11, 5, 6, 0, 7, 1, 8, 2}; - return retval; - } else if (iphi < 3) { - std::vector retval = {7, 1, 8, 2}; - return retval; - } else if (iphi < 5) { - std::vector retval = {9, 3, 10, 4, 7, 1, 8, 2}; - return retval; - } else if (iphi < 6) { - std::vector retval = {9, 3, 10, 4}; - return retval; - } else if (iphi < 8) { - std::vector retval = {9, 3, 10, 4, 11, 5, 6, 0}; - return retval; - } else { - std::vector retval = {11, 5, 6, 0}; - return retval; - } -} - -template <> -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { - const std::pair logic_sr = get_small_region(sr); - return caloLinksHelper(logic_sr.second); -} - -template <> -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t sr) const { - const std::pair logic_sr = get_small_region(sr); - return caloLinksHelper(logic_sr.second); -} - -template <> -inline std::vector l1ct::tdr_alt_regionizer::Regionizer::linksForSR(size_t) const { - std::vector retval = {0}; - return retval; -} - -// This is a port of: -// function get_small_region(index : linear_small_region_t) return eta_phi_small_region_t is -// variable rval : eta_phi_small_region_t; -// begin -// rval.eta_index := index / SMALL_REGION_ETA_COUNT; -// rval.phi_index := index rem SMALL_REGION_ETA_COUNT; -// return rval; -// end function get_small_region; -template -std::pair l1ct::tdr_alt_regionizer::Regionizer::get_small_region(size_t sr) const { - std::pair rval; - rval.second = sr / SMALL_REGION_ETA_COUNT; - rval.first = sr % SMALL_REGION_ETA_COUNT; - return rval; -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::run() { - if (debug_) - printDebug(-1); - - for (size_t sr = 0; sr < regionmap_.size(); sr++) { - // iterate over the (logical) SRs - auto links = linksForSR(sr); // these are the logical links - auto physSR = regionmap_[sr]; - bool allEmpty; - do { - allEmpty = true; - for (auto link : links) { - auto &buffer = buffers_[sectorMapLogToPhys_[link]]; - if (!buffer.empty(sr)) { - allEmpty = false; - addToSmallRegion(physSR, buffer.getEntry(sr)); - } - } - } while (!allEmpty); - } - if (debug_) - printDebug(1); -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::reset() { - for (auto& buffer : buffers_) { - buffer.reset(); - } - clearSmallRegions(); -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::clearSmallRegions() { - for (auto& smallRegionObject : smallRegionObjects_) { - smallRegionObject.clear(); - } -} - -template -void l1ct::tdr_alt_regionizer::Regionizer::printDebug(int count) const { - dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl; - dbgCout() << count << "\tbuffer\tphysreg\titem\tpt\teta\tphi\t" << std::endl; - for (size_t logSector = 0; logSector < sectorMapLogToPhys_.size(); logSector++) { - auto physSector = sectorMapLogToPhys_[logSector]; - buffers_[physSector].printDebug(physSector, logSector); - } - - dbgCout() << "SMALL REGIONS" << std::endl; - for (unsigned int region = 0; region < regionmap_.size(); region++) { - dbgCout() << count << "\tregion\t\tphysRegion\titem\tpt\tloceta\tlocphi" << std::endl; - auto physRegIdx = regionIndex(region); - auto etaC = regions_[physRegIdx].intEtaCenter(); - auto phiC = regions_[physRegIdx].intPhiCenter(); - for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) { - dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" << physRegIdx << "\t" - << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t" - << smallRegionObjects_[region][j].intPhi() << std::endl; - } - dbgCout() << "-------------------------------" << std::endl; - } - dbgCout() << "\n-------------------------------" << std::endl; -} - -// returns 2D arrays, sectors (links) first dimension, objects second -template -std::vector> l1ct::tdr_alt_regionizer::Regionizer::fillLinks( - const std::vector>& sectors) const { - std::vector> links; - - if (maxobjects_ == 0) { - return links; - } - //one link per sector - for (const auto& sector : sectors) { - links.emplace_back(); - for (unsigned int io = 0; io < sector.size(); io++) { - links.back().push_back(sector[io]); - } - } - - return links; -} - -template -std::vector> l1ct::tdr_alt_regionizer::Regionizer::fillLinks(const DetectorSector& sector) const { - std::vector> links; - - if (maxobjects_ == 0) { - return links; - } - - links.emplace_back(); - for (unsigned int io = 0; io < sector.size(); io++) { - links.back().push_back(sector[io]); - } - return links; -} diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h deleted file mode 100644 index 7fe1454aa9fe7..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef tdr_alt_regionizer_ref_h -#define tdr_alt_regionizer_ref_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.h" - -// This is the second, alternate implementation of the TDR regionizer, which doesn't use a pipe for overlaps - - -namespace edm { - class ParameterSet; - class ParameterSetDescription; -} // namespace edm - -namespace l1ct { - class TDRAltRegionizerEmulator : public RegionizerEmulator { - public: - TDRAltRegionizerEmulator(uint32_t ntk, - uint32_t ncalo, - uint32_t nem, - uint32_t nmu, - bool debug_tk = false, - bool debug_calo = false, - bool debug_emcalo = false, - bool debug_mu = false); - - // note: this one will work only in CMSSW - TDRAltRegionizerEmulator(const edm::ParameterSet& iConfig); - - ~TDRAltRegionizerEmulator() override; - - static edm::ParameterSetDescription getParameterSetDescription(); - - void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; - - void run(const RegionizerDecodedInputs& in, std::vector& out) override; - - private: - /// The maximum number of objects of each type to output per small region - uint32_t ntk_, ncalo_, nem_, nmu_; - - bool init_; // has initialization happened - - tdr_alt_regionizer::Regionizer tkRegionizers_; - tdr_alt_regionizer::Regionizer hadCaloRegionizers_; - tdr_alt_regionizer::Regionizer emCaloRegionizers_; - tdr_alt_regionizer::Regionizer muRegionizers_; - }; - -} // namespace l1ct - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index 0bedb18a32fe5..076208a89185e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -22,120 +22,16 @@ namespace l1ct { return local_phi; } - /// corresponds to level1_to_2_pipe_t in firmware - template - class PipeEntry { - public: - PipeEntry() : obj_(), sr_(-1) {} - PipeEntry(const T& obj, int sr, int glbeta, int glbphi) : obj_(obj), sr_(sr), glbeta_(glbeta), glbphi_(glbphi) {} - - int sr() const { return sr_; } - - // Note, this returns a copy so you can modify - T obj() const { return obj_; } - - bool valid() const { return sr_ >= 0; } - - void setInvalid() { sr_ = -1; } - - int pt() const { return obj_.intPt(); } - int glbPhi() const { return glbphi_; } - int glbEta() const { return glbeta_; } - - private: - T obj_; - /// the SR linearized indices (can index regionmap_) where this object needs to go; -1 means invalid - int sr_; - /// The global eta and phi of the object (hard to get with duplicates) - int glbeta_, glbphi_; - }; - - /// The pipe, with multiple inputs and one output - template - class Pipe { - public: - /// if using the default constructor, have to call setTaps before use - Pipe() : pipe_() {} - - Pipe(size_t ntaps) : pipe_(ntaps) {} - - void setTaps(size_t taps) { pipe_.resize(taps); } - - /// check if the entry is valid (i.e. already has data) - bool valid(size_t idx) const { return pipe_.at(idx).valid(); } - - /// should check if valid before adding an entry - void addEntry(size_t idx, const PipeEntry& entry) { pipe_[idx] = entry; } - - /// perform one tick, shifting all the entries to higher indices, and returning the last - PipeEntry popEntry(); - - void reset(); - - size_t size() const { return pipe_.size(); } - - /// for debug - const PipeEntry& entry(size_t idx) const { return pipe_[idx]; } - - private: - std::vector> pipe_; - }; - - /// The pipe, with multiple inputs and one output - template - class Pipes { - public: - /// the number of pipes - Pipes(size_t nregions) : pipes_(nregions / SRS_PER_RAM) {} - - /// set the number of taps in each pipe - void setTaps(size_t taps); - - /// check if the entry is valid (i.e. already has data) - bool valid(int sr, size_t logicBufIdx) const { return pipes_[pipeIndex(sr)].valid(logicBufIdx); } - - /// should check if valid before adding an entry - void addEntry(int sr, size_t logicBufIdx, const PipeEntry& entry) { - pipes_[pipeIndex(sr)].addEntry(logicBufIdx, entry); - } - - /// perform one tick, shifting all the entries to higher indices, and returning the last - PipeEntry popEntry(size_t pipe) { return pipes_[pipe].popEntry(); }; - - void reset(); - - size_t size() const { return pipes_.size(); } - - size_t numTaps() const { return pipes_.at(0).size(); } - - /// for debug - const PipeEntry& entry(size_t pipe, size_t tap) const { return pipes_[pipe].entry(tap); } - - private: - /// SRs share RAMs (and hardware pipes) - static size_t constexpr SRS_PER_RAM = 2; - - /// Because some SRs share pipes, this determines the pipe index for a linearize SR index - /// (This is based on the VHDL function, get_target_pipe_index_subindex) - size_t pipeIndex(int sr) const { return sr / SRS_PER_RAM; } - - std::vector> pipes_; - }; - /// the components that make up the L1 regionizer buffer template class BufferEntry { public: BufferEntry() {} - BufferEntry(const T& obj, std::vector srIndices, int glbeta, int glbphi, bool duplicate, unsigned int clk); + BufferEntry(const T& obj, int glbeta, int glbphi); - unsigned int clock() const { return linkobjclk_; } - int nextSR() const { return (objcount_ < srIndices_.size()) ? srIndices_[objcount_] : -1; } - void incSR() { objcount_++; } int pt() const { return obj_.intPt(); } int glbPhi() const { return glbphi_; } int glbEta() const { return glbeta_; } - int duplicate() const { return duplicate_; } //T obj() { return obj_; } const T& obj() const { return obj_; } @@ -143,92 +39,42 @@ namespace l1ct { private: T obj_; /// the SR linearized indices (can index regionmap_) where this object needs to go - std::vector srIndices_; - /// The global eta and phi of the object (hard to get with duplicates) int glbeta_, glbphi_; - /// Is this a duplciate that should be ignored? used for GCT duplicate removal - bool duplicate_; - unsigned int linkobjclk_, objcount_; }; /// The L1 regionizer buffer (corresponding to level1_fifo_buffer.vhd) template class Buffer { public: - Buffer() : clkindex360_(INIT360), clkindex240_(INIT240), timeOfNextObject_(-1) {} + Buffer() {} void addEntry(const T& obj, - std::vector srs, + std::vector srs, // LOGICAL SRs int glbeta, - int glbphi, - bool duplicate, // this is mainly for GCT, is it one of the duplicates - unsigned int dupNum, // this is for the (currently unused) feature of multiple buffers per sector - unsigned int ndup); - - BufferEntry& front() { return data_.front(); } - const BufferEntry& front() const { return data_.front(); } - - /// sets the next time something is taken from this buffer - void updateNextObjectTime(int currentTime, bool incrementTime = true); - - /// delete the front element - void pop() { data_.pop_front(); } + int glbphi); - // mostly for debug - unsigned int clock(unsigned int index = 0) const { return data_[index].clock(); } - int pt(unsigned int index = 0) const { return data_[index].pt(); } - int glbPhi(unsigned int index = 0) const { return data_[index].glbPhi(); } - int glbEta(unsigned int index = 0) const { return data_[index].glbEta(); } - int duplicate(unsigned int index = 0) const { return data_[index].duplicate(); } + bool empty(size_t sr) const; + BufferEntry getEntry(size_t sr); - unsigned int numEntries() const { return data_.size(); } + // mainly for debug/validation, to check that nothing is left over after an event + // This is the number of entries in all the deques, not necessarily the number of + // entries in the map. + unsigned int numEntries() const; - /// pop the first entry, formatted for inclusion in pipe - PipeEntry popEntry(int currTime, bool debug); + void reset() { data_.clear(); } - int timeOfNextObject() const { return timeOfNextObject_; } - - void reset() { - clkindex360_ = INIT360; - clkindex240_ = INIT240; - data_.clear(); - timeOfNextObject_ = -1; - } + void printDebug(size_t bufIdx, size_t logBufIdx) const; private: - // used when building up the linkobjclk_ entries for the BufferEntries - unsigned int nextObjClk(unsigned int ndup, bool skip); // may need to treat pt == 0 and overlap differently - // transient--used only during event construction, not used after - // Counts in 1.39ns increments (i.e. 360 increments by 2, 240 by 3) - unsigned int clkindex360_; - unsigned int clkindex240_; - - // These values represent at what clock count the first data arrives, counting in 1.39ns increments (2 increments - // for one 360MHz clock period, 3 increments for a 240MHz clock period). The 360 version refers to the data as it - // is transferred over the fibers, while the 240 is for data going to the regionizer. Some data is thrown out in between. - // Both counts are used to determine when the data reaches the regionizer. - static unsigned int constexpr INIT360 = 2; - static unsigned int constexpr INIT240 = 4; - - /// The actual data - std::deque> data_; - - /// the time of the next object in the buffer (-1 if none) - int timeOfNextObject_; + /// The actual data, indexed by the physical SR + std::map>> data_; }; template class Regionizer { public: Regionizer() = delete; - Regionizer(unsigned int neta, - unsigned int nphi, //the number of eta and phi SRs in a big region (board) - unsigned int maxobjects, - int bigRegionMin, - int bigRegionMax, // the phi range covered by this board - unsigned int nclocks, - unsigned int ndup = 1, // how much one duplicates the inputs (to increase processing bandwidth) - bool debug = false); + Regionizer(unsigned int maxobjects, bool debug = false); void initSectors(const std::vector>& sectors); void initSectors(const DetectorSector& sector); @@ -241,32 +87,34 @@ namespace l1ct { void reset(); - /// Return a map of of the SRs indexed by SR index (covering only those from board) - std::map> fillRegions(bool doSort); + const std::vector>& smallRegions() const { return smallRegionObjects_; } + void clearSmallRegions(); void printDebug(int count) const; private: - /// is the given small region in the big region - bool isInBigRegion(const PFRegionEmu& reg) const; + const size_t SMALL_REGION_ETA_COUNT = 6; + const size_t SMALL_REGION_PHI_COUNT = 9; + + /// @brief convert to logical SR + /// @param sr linear small region + /// @return pair (eta, phi) region index) + std::pair get_small_region(size_t sr) const; - /// Does the given region fit in the big region, taking into account overlaps? - bool isInBigRegionLoose(const PFRegionEmu& reg) const; + /// logical links associated with a logical sr (customized for each type) + std::vector linksForSR(size_t sr) const; + std::vector caloLinksHelper(size_t iphi) const; unsigned int numBuffers() const { return buffers_.size(); } unsigned int numEntries(unsigned int bufferIndex) const { return buffers_[bufferIndex].numEntries(); } std::vector getSmallRegions(int glbeta, int glbphi) const; - void addToBuffer(const T& obj, unsigned int index, unsigned int dupNum); - void setBuffer(const std::vector& objvec, unsigned int index); + /// fill the buffers with an event's link data. The buffers should be empty--checked by assert void setBuffers(const std::vector>&& objvecvec); - /// This retruns the linearized small region associated with the given item (-1 is throwout) - int nextSR(unsigned int linknum, unsigned int index = 0) { return buffers_[linknum].nextSR(index); } - - /// 'put' object in small region - void addToSmallRegion(PipeEntry&&); + /// 'put' object in small region. The sr is physics + void addToSmallRegion(size_t sr, BufferEntry&& bufEntry); /// returns 2D arrays, sectors (links) first dimension, objects second std::vector> fillLinks(const std::vector>& sectors) const; @@ -275,10 +123,11 @@ namespace l1ct { // this function is for sorting small regions first in phi and then in eta. // It takes regions_ indices bool sortRegionsRegular(size_t a, size_t b) const; + bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; + // This is for sorting sectors. It sorts in eta first, then phi bool sortSectors(size_t a, size_t b) const; - - bool sortRegionsHelper(int etaa, int etab, int phia, int phib) const; + bool sortSectorsHelper(int etaa, int etab, int phia, int phib) const; /// get the index in regions_ for a particular SR. size_t regionIndex(int sr) const { return regionmap_.at(sr); } @@ -286,26 +135,10 @@ namespace l1ct { /// get the logical buffer index (i.e. the index in the order in the firmware) size_t logicBuffIndex(size_t bufIdx) const; - /// GCT sends duplicates. This indicates if an entry is a duplicate - /// For other objects, it always returns false - bool isDuplicate(int locphi, size_t logicBufIdx) const; - - /// The numbers of eta and phi in a big region (board) - unsigned int neta_, nphi_; /// The maximum number of objects to output per small region unsigned int maxobjects_; - /// The number of input sectors for this type of device - unsigned int nsectors_; - /// the minimum phi of this board - int bigRegionMin_; - /// the maximum phi of this board - int bigRegionMax_; - /// the number of clocks to receive one event - unsigned int nclocks_; - /// How many buffers per link (default 1) - unsigned int ndup_; - - /// the region information associated with each input sector + + /// the region information associated with each input sector (link). Note, this is indexed in physical order std::vector sectors_; /// the region information associated with each SR @@ -320,21 +153,12 @@ namespace l1ct { /// the inverse mapping of sectormap_ (only used for debug printing) std::vector sectorMapLogToPhys_; - /// The buffers. There are ndup_ buffers per link/sector + /// The buffers. There is one buffer per link (or sector). Note, this is also indexed in physical order (= same index as sectors) std::vector> buffers_; - /// The pipes, one per ram (see SRS_PER_RAM) - Pipes pipes_; - /// The objects in each small region handled in board; Indexing corresponds to that in regionmap_ std::vector> smallRegionObjects_; - /// Whether this is the first event (since timing is a bit different then) - bool firstEvent_; - - /// This is the delay (only applied after first event) before processing starts - static unsigned int constexpr DELAY_TO_START = 10; - bool debug_; }; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index 30c0dcc782929..8163c6749c988 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -1,180 +1,68 @@ #include #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h" - -// PIPE ENTRY AND BUFFER -template -l1ct::tdr_regionizer::PipeEntry l1ct::tdr_regionizer::Pipe::popEntry() { - assert(pipe_.size() > 0); - auto last = pipe_.back(); - // shift one over - for (size_t i = pipe_.size() - 1; i > 0; --i) { - pipe_[i] = pipe_[i - 1]; - } - pipe_[0].setInvalid(); - return last; -} - -template -void l1ct::tdr_regionizer::Pipe::reset() { - for (auto& pe : pipe_) { - pe.setInvalid(); - } -} - -template -void l1ct::tdr_regionizer::Pipes::reset() { - for (auto& pipe : pipes_) { - pipe.reset(); - } -} - -template -void l1ct::tdr_regionizer::Pipes::setTaps(size_t taps) { - for (auto& pipe : pipes_) { - pipe.setTaps(taps); - } -} +#include "FWCore/MessageLogger/interface/MessageLogger.h" // BUFFER ENTRY AND BUFFER template -l1ct::tdr_regionizer::BufferEntry::BufferEntry( - const T& obj, std::vector srIndices, int glbeta, int glbphi, bool duplicate, unsigned int clk) - : obj_(obj), srIndices_(srIndices), glbeta_(glbeta), glbphi_(glbphi), duplicate_(duplicate), linkobjclk_(clk) { - objcount_ = 0; -} +l1ct::tdr_regionizer::BufferEntry::BufferEntry(const T& obj, int glbeta, int glbphi) + : obj_(obj), glbeta_(glbeta), glbphi_(glbphi) {} template -inline void l1ct::tdr_regionizer::Buffer::addEntry( - const T& obj, - std::vector srIndices, - int glbeta, - int glbphi, - bool duplicate, // this is mainly for GCT, is it one of the duplicates - unsigned int dupNum, - unsigned int ndup) { - // dupNum is the duplicate number of this buffer (int range 0 to ndup_-1) - auto objClk = nextObjClk(ndup, obj.intPt() == 0); - data_.emplace_back(obj, srIndices, glbeta, glbphi, duplicate, objClk); - if (timeOfNextObject_ < 0) { - timeOfNextObject_ = objClk; +inline void l1ct::tdr_regionizer::Buffer::addEntry(const T& obj, + std::vector srIndices, + int glbeta, + int glbphi) { + for (auto sr : srIndices) { + data_[sr].emplace_back(obj, glbeta, glbphi); // note, this creates a deque if needed } } template -void l1ct::tdr_regionizer::Buffer::updateNextObjectTime(int currTime, bool incrementTime) { - if (data_.size() > 0) { - auto nextTime = incrementTime ? currTime + 1 : currTime; - timeOfNextObject_ = std::max(front().clock(), static_cast(nextTime)); +inline bool l1ct::tdr_regionizer::Buffer::empty(size_t sr) const { + auto it = data_.find(sr); + if (it != data_.end()) { + return it->second.empty(); } else { - timeOfNextObject_ = -1; + return true; } } template -inline unsigned int l1ct::tdr_regionizer::Buffer::nextObjClk(unsigned int ndup, bool skip) { - unsigned int nextVal = std::max(clkindex360_, clkindex240_) / 3; - - clkindex360_ += 2 * ndup; - - // Though a 360MHz clock is used, one doesn't need to a 240MHz clock for pt == 0 - if (!skip) { - clkindex240_ += 3; - } - return nextVal; +inline l1ct::tdr_regionizer::BufferEntry l1ct::tdr_regionizer::Buffer::getEntry(size_t sr) { + BufferEntry entry = data_[sr].front(); + data_[sr].pop_front(); + return entry; } -// explicit for tracks -template <> -inline unsigned int l1ct::tdr_regionizer::Buffer::nextObjClk(unsigned int ndup, bool skip) { - if (ndup != 1) { - throw std::invalid_argument("Only ndup==1 is currently supported for the TkObjEmu buffers."); - } - - unsigned int nextVal = std::max(clkindex360_, clkindex240_) / 3; - - clkindex360_ += 2; - if ((clkindex360_ - INIT360) % 6 == 4) { - clkindex360_ += 2; - } - - if (!skip) { - clkindex240_ += 3; +template +unsigned int l1ct::tdr_regionizer::Buffer::numEntries() const { + unsigned int count = 0; + for (const auto& [key, value] : data_) { + count += value.size(); } - return nextVal; + return count; } template -l1ct::tdr_regionizer::PipeEntry l1ct::tdr_regionizer::Buffer::popEntry(int currTime, bool debug) { - if (front().nextSR() < 0) { - // throwout - pop(); - if (debug) { - dbgCout() << "updating time clock = " << front().clock() << ", currTime = " << currTime << std::endl; - } - updateNextObjectTime(currTime); - return l1ct::tdr_regionizer::PipeEntry(); - } - - auto pipeEntry = - l1ct::tdr_regionizer::PipeEntry(front().obj(), front().nextSR(), front().glbEta(), front().glbPhi()); - front().incSR(); - if (front().nextSR() < 0) { - // no more SRs for current front - pop(); - } else { - if (debug) { - dbgCout() << "Remain on same object, nextSR = " << front().nextSR() << std::endl; +void l1ct::tdr_regionizer::Buffer::printDebug(size_t bufferIdx, size_t logBufIdx) const { + for (auto srq_it = data_.rbegin(); srq_it != data_.rend(); ++srq_it) { + for (unsigned int j = 0; j < srq_it->second.size(); j++) { + dbgCout() << logBufIdx << "\t" << bufferIdx << "\t" << srq_it->first << "\t" << j << "\t" + << srq_it->second[j].pt() << "\t" << srq_it->second[j].glbEta() << "\t" << srq_it->second[j].glbPhi() + << std::endl; } - // this is a processing_stall, but throwouts that follow can still be dropped - // due to the pipeline have to look two ticks back - if (numEntries() > 1 && data_[1].nextSR() == -1 && static_cast(data_[1].clock()) == currTime + 2) { - if (debug) { - dbgCout() << "removing a following throwout with time " << data_[1].clock() << std::endl; - } - data_.erase(data_.begin() + 1); - } else if (numEntries() > 2 && data_[2].nextSR() == -1 && static_cast(data_[2].clock()) <= currTime + 2) { - if (debug) { - dbgCout() << "removing the two-back throwout with time " << data_[2].clock() << std::endl; - } - data_.erase(data_.begin() + 2); - } - } - if (debug) { - dbgCout() << "updating time clock = " << front().clock() << ", currTime = " << currTime << std::endl; + dbgCout() << "-------------------------------" << std::endl; } - - updateNextObjectTime(currTime); - return pipeEntry; } // REGIONIZER template -l1ct::tdr_regionizer::Regionizer::Regionizer(unsigned int neta, - unsigned int nphi, - unsigned int maxobjects, - int bigRegionMin, - int bigRegionMax, - unsigned int nclocks, - unsigned int ndup, - bool debug) - : neta_(neta), - nphi_(nphi), - maxobjects_(maxobjects), - nsectors_(0), - bigRegionMin_(bigRegionMin), - bigRegionMax_(bigRegionMax), - nclocks_(nclocks), - ndup_(ndup), - pipes_(neta * nphi), - smallRegionObjects_(neta * nphi), - firstEvent_(true), - debug_(debug) {} +l1ct::tdr_regionizer::Regionizer::Regionizer(unsigned int maxobjects, bool debug) + : maxobjects_(maxobjects), debug_(debug) {} template void l1ct::tdr_regionizer::Regionizer::initSectors(const std::vector>& sectors) { - assert(nsectors_ == 0); - // we need a mapping of physical (what's in the sectors variable) to logical, // but it's easier to create the inverse, first @@ -187,17 +75,17 @@ void l1ct::tdr_regionizer::Regionizer::initSectors(const std::vector @@ -238,11 +121,10 @@ void l1ct::tdr_regionizer::Regionizer::fillBuffers(const DetectorSector& s setBuffers(fillLinks(sector)); } -// this function is for sorting small regions -// in eta first, then in phi +// this function is for sorting small regions; For consistency with new regionizer, swap order. +// New order: in phi first, then in eta template bool l1ct::tdr_regionizer::Regionizer::sortRegionsRegular(size_t a, size_t b) const { - // first do eta auto etaa = regions_[a].intEtaCenter(); auto etab = regions_[b].intEtaCenter(); auto phia = regions_[a].intPhiCenter(); @@ -251,9 +133,29 @@ bool l1ct::tdr_regionizer::Regionizer::sortRegionsRegular(size_t a, size_t b) } // this function is for sorting small regions -// in eta first, then in phi +// in phi first, then in eta template bool l1ct::tdr_regionizer::Regionizer::sortRegionsHelper(int etaa, int etab, int phia, int phib) const { + // first do phi + if (phia < phib) { + return true; + } else if (phia > phib) { + return false; + } + + // Only here if have same phi + if (etaa < etab) { + return true; + } else { + return false; + } +} + +// this function is for sorting Sectors (mainly tracker) +// note it is opposite of regions to keep consistent +// It sorts in eta first, then phi +template +bool l1ct::tdr_regionizer::Regionizer::sortSectorsHelper(int etaa, int etab, int phia, int phib) const { // first do eta if (etaa < etab) { return true; @@ -261,17 +163,7 @@ bool l1ct::tdr_regionizer::Regionizer::sortRegionsHelper(int etaa, int etab, return false; } - // if here, then etaa == etab, move to phi - if (bigRegionMax_ < bigRegionMin_) { - // the wraparound case, rewrap around pi - if (phia < 0) { - phia += l1ct::Scales::INTPHI_TWOPI; - } - if (phib < 0) { - phib += l1ct::Scales::INTPHI_TWOPI; - } - } - // regular phi + // Only here if have same eta if (phia < phib) { return true; } else { @@ -288,77 +180,32 @@ bool l1ct::tdr_regionizer::Regionizer::sortSectors(size_t a, size_t b) const auto etab = sectors_[b].intEtaCenter(); auto phia = sectors_[a].intPhiCenter(); auto phib = sectors_[b].intPhiCenter(); - return sortRegionsHelper(etaa, etab, phia, phib); + return sortSectorsHelper(etaa, etab, phia, phib); } template void l1ct::tdr_regionizer::Regionizer::initRegions(const std::vector& regions) { regions_.resize(regions.size()); + smallRegionObjects_.resize(regions.size()); for (unsigned int i = 0; i < regions.size(); ++i) { regions_[i] = regions[i].region; - if (isInBigRegion(regions_[i])) { - regionmap_.push_back(i); - if (debug_) { - dbgCout() << "region [" << i << "] eta/phi: " << regions_[i].intEtaCenter() << " " << regions_[i].intPhiCenter() - << ", eta half width = " << regions_[i].hwEtaHalfWidth.to_int() - << ", phi half width = " << regions_[i].hwPhiHalfWidth.to_int() - << ", eta extra = " << regions_[i].hwEtaExtra.to_int() - << ", phi extra = " << regions_[i].hwPhiExtra.to_int() << std::endl; - } + regionmap_.push_back(i); + if (debug_) { + dbgCout() << "region [" << i << "] eta/phi: " << regions_[i].intEtaCenter() << " " << regions_[i].intPhiCenter() + << ", eta half width = " << regions_[i].hwEtaHalfWidth.to_int() + << ", phi half width = " << regions_[i].hwPhiHalfWidth.to_int() + << ", eta extra = " << regions_[i].hwEtaExtra.to_int() + << ", phi extra = " << regions_[i].hwPhiExtra.to_int() << std::endl; } } - assert(regionmap_.size() == neta_ * nphi_); std::sort( regionmap_.begin(), regionmap_.end(), [this](size_t a, size_t b) { return this->sortRegionsRegular(a, b); }); -} - -template -bool l1ct::tdr_regionizer::Regionizer::isInBigRegion(const PFRegionEmu& reg) const { - auto phi = reg.intPhiCenter(); - if (bigRegionMax_ < bigRegionMin_) { - // the wraparound case - return phi > bigRegionMin_ || phi < bigRegionMax_; - } else { - // the normal case - return phi > bigRegionMin_ && phi < bigRegionMax_; - } -} - -template -bool l1ct::tdr_regionizer::Regionizer::isInBigRegionLoose(const PFRegionEmu& reg) const { - auto phi = reg.intPhiCenter(); - auto brmax = phi_wrap(bigRegionMax_ + reg.hwPhiHalfWidth.to_int() + reg.hwPhiExtra.to_int()); - auto brmin = phi_wrap(bigRegionMin_ - reg.hwPhiHalfWidth.to_int() - reg.hwPhiExtra.to_int()); - if (brmax < brmin) { - // the wraparound case - return phi > brmin || phi < brmax; - } else { - // the normal case - return phi > brmin && phi < brmax; - } -} - -template <> -inline bool l1ct::tdr_regionizer::Regionizer::isInBigRegionLoose(const PFRegionEmu& reg) const { - return isInBigRegion(reg); -} - -template <> -inline bool l1ct::tdr_regionizer::Regionizer::isInBigRegionLoose(const PFRegionEmu& reg) const { - return isInBigRegion(reg); -} -template <> -inline bool l1ct::tdr_regionizer::Regionizer::isInBigRegionLoose(const PFRegionEmu& reg) const { - auto phi = reg.intPhiCenter(); - auto brmax = phi_wrap(bigRegionMax_ + 2 * reg.hwPhiHalfWidth.to_int()); - auto brmin = phi_wrap(bigRegionMin_ - 2 * reg.hwPhiHalfWidth.to_int()); - if (brmax < brmin) { - // the wraparound case - return phi > brmin || phi < brmax; - } else { - // the normal case - return phi > brmin && phi < brmax; + if (debug_) { + for (auto val : regionmap_) { + dbgCout() << "regionmap_ phys index = " << val << ", eta = " << regions_[val].intEtaCenter() + << ", phi = " << regions_[val].intPhiCenter() << std::endl; + } } } @@ -379,261 +226,210 @@ std::vector l1ct::tdr_regionizer::Regionizer::getSmallRegions(int glb } } - // In a silly convention, the order of these nneds to be modified if there are 4. - if (srIndices.size() == 4) { - auto ent1 = srIndices[1]; - srIndices[1] = srIndices[2]; - srIndices[2] = ent1; - } return srIndices; } -template -void l1ct::tdr_regionizer::Regionizer::addToBuffer(const T& obj, unsigned int buffer, unsigned int dupNum) { - assert(buffer < numBuffers()); - const unsigned int sector = buffer / ndup_; - auto glbphi = sectors_[sector].hwGlbPhiOf(obj).to_int(); - auto glbeta = sectors_[sector].hwGlbEtaOf(obj).to_int(); - // get the SR indices that this object should go into - buffers_[buffer].addEntry(obj, - getSmallRegions(glbeta, glbphi), - glbeta, - glbphi, - isDuplicate(obj.hwPhi.to_int(), logicBuffIndex(buffer)), - dupNum, - ndup_); -} - -template -void l1ct::tdr_regionizer::Regionizer::setBuffer(const std::vector& objvec, unsigned int buffer) { - assert(buffer < numBuffers()); - buffers_[buffer].reset(); - unsigned int dupNum = buffer % ndup_; - for (unsigned int i = dupNum; i < objvec.size(); i += ndup_) { - if (debug_) { - dbgCout() << "Buffer " << buffer << " dupNum " << dupNum << ": add obj, index " << i - << " with pt = " << objvec[i].intPt() << std::endl; - } - addToBuffer(objvec[i], buffer, dupNum); - } -} - template void l1ct::tdr_regionizer::Regionizer::setBuffers(const std::vector>&& objvecvec) { - assert(numBuffers() == objvecvec.size() * ndup_); + assert(numBuffers() == objvecvec.size()); for (unsigned int buffer = 0; buffer < numBuffers(); buffer++) { - setBuffer(objvecvec[buffer / ndup_], buffer); + assert(buffers_[buffer].numEntries() == 0); // should be empty + for (auto& obj : objvecvec[buffer]) { + auto glbphi = sectors_[buffer].hwGlbPhiOf(obj).to_int(); + auto glbeta = sectors_[buffer].hwGlbEtaOf(obj).to_int(); + if (debug_) { + dbgCout() << "Buffer " << buffer << ": add obj with pt = " << obj.intPt() << ", glb eta = " << glbeta + << ". glb phi = " << glbphi << std::endl; + } + // get the SR indices that this object should go into + auto srs = getSmallRegions(glbeta, glbphi); + buffers_[buffer].addEntry(obj, srs, glbeta, glbphi); + } } } +// sr is physical template -void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(l1ct::tdr_regionizer::PipeEntry&& pipeEntry) { - if (pipeEntry.valid()) { - auto rawObj = pipeEntry.obj(); +void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntry&& bufEntry) { + auto rawObj = bufEntry.obj(); - // in small region, the relative eta and phi are based on a different center, so need to update - auto realRegIdx = regionIndex(pipeEntry.sr()); - auto etaC = regions_[realRegIdx].intEtaCenter(); - auto phiC = regions_[realRegIdx].intPhiCenter(); + // in small region, the relative eta and phi are based on a different center, so need to update + auto etaC = regions_[sr].intEtaCenter(); + auto phiC = regions_[sr].intPhiCenter(); - int locEta = pipeEntry.glbEta() - etaC; - int locPhi = phi_wrap(pipeEntry.glbPhi() - phiC); + int locEta = bufEntry.glbEta() - etaC; + int locPhi = phi_wrap(bufEntry.glbPhi() - phiC); - rawObj.hwEta = locEta; - rawObj.hwPhi = locPhi; + rawObj.hwEta = locEta; + rawObj.hwPhi = locPhi; - smallRegionObjects_[pipeEntry.sr()].push_back(rawObj); - } + smallRegionObjects_[sr].push_back(rawObj); } +// This is a dummy, should never be used. template -void l1ct::tdr_regionizer::Regionizer::run() { - if (debug_) - printDebug(-1); - - // first event doesn't have a delayed start - int startTime = firstEvent_ ? 0 : DELAY_TO_START; - firstEvent_ = false; - - for (int currTime = startTime; currTime < 972 + startTime; - currTime++) { //this is the max allowable if nothing ever blocks - // not positive where 972 comes from. It seems to be 162 * 6 - - // to exit early - bool processedAll = true; // to be overwritten if not the case +inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { + std::vector retval; + throw cms::Exception("LogicError") << "This should be customized per type."; + return retval; +} - // handle the fifo buffers - for (size_t bufIdx = 0; bufIdx < buffers_.size(); ++bufIdx) { - auto& buffer = buffers_[bufIdx]; - if (buffer.timeOfNextObject() >= 0) { - processedAll = false; - } - while (buffer.timeOfNextObject() == currTime) { - // time to handle the buffer entry - const auto nextSR = buffer.front().nextSR(); - if (debug_) { - dbgCout() << "Current time " << currTime << ", handling bufIdx " << bufIdx << ", logical " - << logicBuffIndex(bufIdx) << " object with SR = " << nextSR << ", pt = " << buffer.pt() - << ", glbeta = " << buffer.glbEta() << ", glbphi = " << buffer.glbPhi() - << ", duplicate = " << buffer.duplicate() << std::endl; - } - if (buffer.pt() == 0) { // double check that this also works for tracks - if (debug_) { - dbgCout() << "---Throw out, don't increment time" << std::endl; - } - buffer.pop(); - buffer.updateNextObjectTime(currTime, false); // do not increment time - } else if (buffer.duplicate()) { - // remove the whole object, not worrying about nextSR - if (debug_) { - dbgCout() << "---Throw out, duplicate, increment time" << std::endl; - } - buffer.pop(); - buffer.updateNextObjectTime(currTime); // do increment time - } else if (nextSR < 0 || smallRegionObjects_[nextSR].size() == maxobjects_) { - // throwout or SR full, just get rid of object - if (debug_) { - dbgCout() << "---Throw out" << std::endl; - } - buffer.popEntry(currTime, debug_); - } else { - const auto logicBufIdx = logicBuffIndex(bufIdx); - if (pipes_.valid(nextSR, logicBufIdx)) { - // The pipe already has an entry, so wait till space is available - buffer.updateNextObjectTime(currTime); - } else { - // put the value in the pipe - pipes_.addEntry(nextSR, logicBufIdx, buffer.popEntry(currTime, debug_)); - } - } - } +template <> +inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { + std::pair logic_sr = get_small_region(sr); + const auto& ieta = logic_sr.first; + const auto& iphi = logic_sr.second; + std::vector retval; + if (ieta < 3) { + auto nom = iphi; + auto smaller = (nom == 0) ? 8 : nom - 1; + auto bigger = (nom == 8) ? 0 : nom + 1; + retval.push_back(nom); + retval.push_back(smaller); + retval.push_back(bigger); + if (ieta == 2) { + // also add the other ones + retval.push_back(nom + 9); + retval.push_back(smaller + 9); + retval.push_back(bigger + 9); } - - if (debug_) - printDebug(currTime); - - // add the small regions - for (size_t i = 0; i < pipes_.size(); i++) { - addToSmallRegion(pipes_.popEntry(i)); + } else { + auto nom = iphi + 9; + auto smaller = (nom == 9) ? 17 : nom - 1; + auto bigger = (nom == 17) ? 9 : nom + 1; + retval.push_back(nom); + retval.push_back(smaller); + retval.push_back(bigger); + if (ieta == 3) { + // also add the other ones + retval.push_back(nom - 9); + retval.push_back(smaller - 9); + retval.push_back(bigger - 9); } + } + return retval; +} + +// slighlty more complicated because of logical index; +template +inline std::vector l1ct::tdr_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { + if (iphi < 2) { + std::vector retval = {11, 5, 6, 0, 7, 1, 8, 2}; + return retval; + } else if (iphi < 3) { + std::vector retval = {7, 1, 8, 2}; + return retval; + } else if (iphi < 5) { + std::vector retval = {9, 3, 10, 4, 7, 1, 8, 2}; + return retval; + } else if (iphi < 6) { + std::vector retval = {9, 3, 10, 4}; + return retval; + } else if (iphi < 8) { + std::vector retval = {9, 3, 10, 4, 11, 5, 6, 0}; + return retval; + } else { + std::vector retval = {11, 5, 6, 0}; + return retval; + } +} - // check ot see if you have processed all - if (processedAll) { - // first clear the pipes - for (size_t tap = 0; tap < pipes_.numTaps(); tap++) { - // add the small regions - for (size_t i = 0; i < pipes_.size(); i++) { - addToSmallRegion(pipes_.popEntry(i)); - } - } - if (debug_) - printDebug(2000); - break; - } - } //end main loop +template <> +inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { + const std::pair logic_sr = get_small_region(sr); + return caloLinksHelper(logic_sr.second); } -template -void l1ct::tdr_regionizer::Regionizer::reset() { - for (auto& buffer : buffers_) { - buffer.reset(); - } - pipes_.reset(); - for (auto& smallRegionObject : smallRegionObjects_) { - smallRegionObject.clear(); - } - firstEvent_ = true; +template <> +inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { + const std::pair logic_sr = get_small_region(sr); + return caloLinksHelper(logic_sr.second); } -template -std::map> l1ct::tdr_regionizer::Regionizer::fillRegions(bool doSort) { - std::map> srMap; - for (size_t sr = 0; sr < smallRegionObjects_.size(); sr++) { - srMap[regionIndex(sr)] = smallRegionObjects_[sr]; - if (doSort) { - std::sort(srMap[regionIndex(sr)].begin(), srMap[regionIndex(sr)].end(), std::greater<>()); - } - } - return srMap; +template <> +inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { + std::vector retval = {0}; + return retval; } +// This is a port of: +// function get_small_region(index : linear_small_region_t) return eta_phi_small_region_t is +// variable rval : eta_phi_small_region_t; +// begin +// rval.eta_index := index / SMALL_REGION_ETA_COUNT; +// rval.phi_index := index rem SMALL_REGION_ETA_COUNT; +// return rval; +// end function get_small_region; template -size_t l1ct::tdr_regionizer::Regionizer::logicBuffIndex(size_t bufIdx) const { - const unsigned int sector = bufIdx / ndup_; - auto logSector = sectorMapPhysToLog_[sector]; - return logSector * ndup_ + bufIdx % ndup_; +std::pair l1ct::tdr_regionizer::Regionizer::get_small_region(size_t sr) const { + std::pair rval; + rval.second = sr / SMALL_REGION_ETA_COUNT; + rval.first = sr % SMALL_REGION_ETA_COUNT; + return rval; } -// default is no duplicates. Note, locPhi is for the sector, not small region template -bool l1ct::tdr_regionizer::Regionizer::isDuplicate(int locphi, size_t logicBufIdx) const { - return false; +void l1ct::tdr_regionizer::Regionizer::run() { + if (debug_) + printDebug(-1); + + for (size_t sr = 0; sr < regionmap_.size(); sr++) { + // iterate over the (logical) SRs + auto links = linksForSR(sr); // these are the logical links + auto physSR = regionmap_[sr]; + bool allEmpty; + do { + allEmpty = true; + for (auto link : links) { + auto& buffer = buffers_[sectorMapLogToPhys_[link]]; + if (!buffer.empty(sr)) { + allEmpty = false; + addToSmallRegion(physSR, buffer.getEntry(sr)); + } + } + } while (!allEmpty); + } + if (debug_) + printDebug(1); } -// specialize for GCT (CHECK ESPECIALLY EDGES) -template <> -inline bool l1ct::tdr_regionizer::Regionizer::isDuplicate(int locphi, size_t logicBufIdx) const { - auto odd = logicBufIdx % 2; - if (odd) { - return locphi <= -120; - } else { - return locphi > 120; +template +void l1ct::tdr_regionizer::Regionizer::reset() { + for (auto& buffer : buffers_) { + buffer.reset(); } + clearSmallRegions(); } -template <> -inline bool l1ct::tdr_regionizer::Regionizer::isDuplicate(int locphi, size_t logicBufIdx) const { - auto odd = logicBufIdx % 2; - if (odd) { - return locphi <= -120; - } else { - return locphi > 120; +template +void l1ct::tdr_regionizer::Regionizer::clearSmallRegions() { + for (auto& smallRegionObject : smallRegionObjects_) { + smallRegionObject.clear(); } } template void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl; - dbgCout() << count << "\tbuffer\tlogical\titem\tpt\teta\tphi\tduplicate\tclock" << std::endl; - for (auto sector : sectorMapLogToPhys_) { - for (unsigned int dup = 0; dup < ndup_; dup++) { - const unsigned int buffer = sector * ndup_ + dup; - for (unsigned int j = 0; j < numEntries(buffer); j++) { - dbgCout() << "\t" << buffer << "\t" << logicBuffIndex(buffer) << "\t" << j << "\t" << buffers_[buffer].pt(j) - << "\t" << buffers_[buffer].glbEta(j) << "\t" << buffers_[buffer].glbPhi(j) << "\t" - << buffers_[buffer].duplicate(j) << "\t" << buffers_[buffer].clock(j) << std::endl; - } - dbgCout() << "-------------------------------" << std::endl; - } - } - dbgCout() << "PIPES, (for " << pipes_.size() << " pipes)" << std::endl; - dbgCout() << count << "\tpipe\ttap\tsr\tpt\teta\tphi" << std::endl; - for (int tap = pipes_.numTaps() - 1; tap >= 0; --tap) { - for (int pipe = pipes_.size() - 1; pipe >= 0; --pipe) { - auto entry = pipes_.entry(pipe, tap); - dbgCout() << "\t" << pipe << "\t" << tap + 1 << "\t" << entry.sr() << "\t" << entry.pt() << "\t" << entry.glbEta() - << "\t" << entry.glbPhi() << std::endl; - } - dbgCout() << "-------------------------------" << std::endl; + dbgCout() << count << "\tbuffer\tphysreg\titem\tpt\teta\tphi\t" << std::endl; + for (size_t logSector = 0; logSector < sectorMapLogToPhys_.size(); logSector++) { + auto physSector = sectorMapLogToPhys_[logSector]; + buffers_[physSector].printDebug(physSector, logSector); } dbgCout() << "SMALL REGIONS" << std::endl; - for (unsigned int region = 0; region < neta_ * nphi_; region++) { - dbgCout() << count << "\tregion\t\titem\tpt\tloceta\tlocphi" << std::endl; - auto realRegIdx = regionIndex(region); - auto etaC = regions_[realRegIdx].intEtaCenter(); - auto phiC = regions_[realRegIdx].intPhiCenter(); + for (unsigned int region = 0; region < regionmap_.size(); region++) { + dbgCout() << count << "\tregion\t\tphysRegion\titem\tpt\tloceta\tlocphi" << std::endl; + auto physRegIdx = regionIndex(region); + auto etaC = regions_[physRegIdx].intEtaCenter(); + auto phiC = regions_[physRegIdx].intPhiCenter(); for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) { - dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" + dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" << physRegIdx << "\t" << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t" << smallRegionObjects_[region][j].intPhi() << std::endl; } dbgCout() << "-------------------------------" << std::endl; } - dbgCout() << "TIMES" << std::endl; - for (unsigned int i = 0; i < numBuffers(); i++) { - dbgCout() << " " << buffers_[i].timeOfNextObject(); - } dbgCout() << "\n-------------------------------" << std::endl; } @@ -648,11 +444,9 @@ std::vector> l1ct::tdr_regionizer::Regionizer::fillLinks( } //one link per sector for (const auto& sector : sectors) { - if (isInBigRegionLoose(sector.region)) { - links.emplace_back(); - for (unsigned int io = 0; io < sector.size() && io < nclocks_; io++) { - links.back().push_back(sector[io]); - } + links.emplace_back(); + for (unsigned int io = 0; io < sector.size(); io++) { + links.back().push_back(sector[io]); } } @@ -668,7 +462,7 @@ std::vector> l1ct::tdr_regionizer::Regionizer::fillLinks(const } links.emplace_back(); - for (unsigned int io = 0; io < sector.size() && io < nclocks_; io++) { + for (unsigned int io = 0; io < sector.size(); io++) { links.back().push_back(sector[io]); } return links; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h index 737dc32d27b55..eb78f2c3de183 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h @@ -4,6 +4,8 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h" +// This is the second, alternate implementation of the TDR regionizer, which doesn't use a pipe for overlaps + namespace edm { class ParameterSet; class ParameterSetDescription; @@ -16,11 +18,10 @@ namespace l1ct { uint32_t ncalo, uint32_t nem, uint32_t nmu, - uint32_t nclocks, - std::vector bigRegionEdges, - uint32_t netaInBR, - uint32_t nphiInBR, - bool dosort); + bool debug_tk = false, + bool debug_calo = false, + bool debug_emcalo = false, + bool debug_mu = false); // note: this one will work only in CMSSW TDRRegionizerEmulator(const edm::ParameterSet& iConfig); @@ -34,27 +35,15 @@ namespace l1ct { void run(const RegionizerDecodedInputs& in, std::vector& out) override; private: - /// The nubmer of barrel big regions (boards) - uint32_t nBigRegions_; /// The maximum number of objects of each type to output per small region uint32_t ntk_, ncalo_, nem_, nmu_; - /// The number of clocks to receive all data of an event (TMUX18 = 162) - uint32_t nclocks_; - - /// The phi edges of the big regions (boards); one greater than the number of boards - std::vector bigRegionEdges_; - - bool dosort_; - - /// The number of eta and phi small regions in a big region (board) - uint32_t netaInBR_, nphiInBR_; bool init_; // has initialization happened - std::vector> tkRegionizers_; - std::vector> hadCaloRegionizers_; - std::vector> emCaloRegionizers_; - std::vector> muRegionizers_; + tdr_regionizer::Regionizer tkRegionizers_; + tdr_regionizer::Regionizer hadCaloRegionizers_; + tdr_regionizer::Regionizer emCaloRegionizers_; + tdr_regionizer::Regionizer muRegionizers_; }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index e75362d29c3d6..e969d8e8b6475 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -31,7 +31,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h" @@ -54,7 +54,6 @@ #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" - //-------------------------------------------------------------------------------------------------- class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { public: @@ -296,7 +295,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet gctHadInput_ = std::make_unique( iConfig.getParameter("gctHadInputConversionParameters")); } else if (!hadClusters.label().empty() && gctHadInAlgo == "Ideal") { - hadGCTCands_ = consumes(hadClusters); + hadGCTCands_ = consumes(hadClusters); } else if (gctHadInAlgo != "None") { throw cms::Exception("Configuration", "Unsupported gctHadInputConversionAlgo"); } @@ -319,7 +318,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); } else if (regalgo == "TDR") { - regionizer_ = std::make_unique( + regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); } else throw cms::Exception("Configuration", "Unsupported regionizerAlgo"); @@ -421,7 +420,7 @@ void L1TCorrelatorLayer1Producer::fillDescriptions(edm::ConfigurationDescription "Emulator" >> getParDesc("gctHadInputConversion")); // Regionizer auto idealRegPD = getParDesc("regionizerAlgo"); - auto tdrRegPD = getParDesc("regionizerAlgo"); + auto tdrRegPD = getParDesc("regionizerAlgo"); auto multififoRegPD = getParDesc("regionizerAlgo"); auto bfMultififoRegPD = getParDesc("regionizerAlgo"); auto multififoBarrelRegPD = edm::ParameterDescription( @@ -885,7 +884,6 @@ void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet } } - for (const edm::ParameterSet &preg : iConfig.getParameter("rawGCTSectors")) { std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) @@ -1021,25 +1019,25 @@ void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster & unsigned int L1TCorrelatorLayer1Producer::emDecodedIndex(unsigned int linkidx, unsigned int entidx) const { if (entidx < 17) { - return 2*linkidx + 6; + return 2 * linkidx + 6; } else if (entidx < 81) { - return 2*linkidx; + return 2 * linkidx; } else if (entidx < 98) { - return 2*linkidx + 7; + return 2 * linkidx + 7; } else { - return 2*linkidx + 1; + return 2 * linkidx + 1; } } unsigned int L1TCorrelatorLayer1Producer::hadDecodedIndex(unsigned int linkidx, unsigned int entidx) const { if (entidx < 57) { - return 2*linkidx + 6; + return 2 * linkidx + 6; } else if (entidx < 81) { - return 2*linkidx; + return 2 * linkidx; } else if (entidx < 138) { - return 2*linkidx + 7; + return 2 * linkidx + 7; } else { - return 2*linkidx + 1; + return 2 * linkidx + 1; } } @@ -1053,7 +1051,7 @@ void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTDigiClusterLink auto decidx = emDecodedIndex(linkidx, entidx); addDecodedGCTEmCalo(event_.decoded.emcalo[decidx], *p); } - } else if (auto p = std::get_if(& link[entidx])) { + } else if (auto p = std::get_if(&link[entidx])) { // Only do this if using Emulated GCT input, not Ideal. if (hadGCTCands_.isUninitialized()) { event_.raw.gctcluster[linkidx].obj.push_back(p->data()); diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 59865ccd2646e..9e9d7b1eb9180 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -43,7 +43,7 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const configTimeSlices(iConfig, "gct", eventTemplate.raw.gctcluster.size(), gctTimeslices_, gctEmLinksFactor_); gctNumberOfObjects_ = iConfig.getParameter("gctNumberOfObjects"); channelSpecsInput_["gct"] = {tmuxFactor_ * gctTimeslices_, - gctTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gctNumberOfObjects_}; + gctTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gctNumberOfObjects_}; } if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { configTimeSlices(iConfig, "hgc", eventTemplate.raw.hgcalcluster.size(), hgcTimeslices_, hgcLinksFactor_); @@ -194,8 +194,8 @@ edm::ParameterSetDescription L1TCorrelatorLayer1PatternFileWriter::getParameterS description.add("nPFOutMuon", 0); description.ifValue(edm::ParameterDescription("partition", "Barrel", true), - "Barrel" >> (describeTF() and describeGCT() and describeGTT() and - describeGMT() and describePuppi() and describeEG()) or + "Barrel" >> (describeTF() and describeGCT() and describeGTT() and describeGMT() and + describePuppi() and describeEG()) or "HGCal" >> (describeTF() and describeHGC() and describeGTT() and describeGMT() and describePuppi() and describeEG()) or "HGCalNoTk" >> (describeHGC() and describeGMT() and describePuppi()) or diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index d5bdfc1f57853..be38da378599d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -23,7 +23,7 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg l1ct::HadCaloObjEmu calo; calo.clear(); - calo.hwPt = inclus.pt() * inclus.ptLSB(); // the LSB for GCT objects + calo.hwPt = inclus.pt() * inclus.ptLSB(); // the LSB for GCT objects calo.hwEta = l1ct::Scales::makeGlbEta(inclus.eta() * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp deleted file mode 100644 index be674ebe9b0d9..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_alt_regionizer_ref.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_ref.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_alt_regionizer_elements_ref.icc" - -#include - -#ifdef CMSSW_GIT_HASH -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" - -l1ct::TDRAltRegionizerEmulator::TDRAltRegionizerEmulator(const edm::ParameterSet& iConfig) - : TDRAltRegionizerEmulator(iConfig.getParameter("nTrack"), - iConfig.getParameter("nCalo"), - iConfig.getParameter("nEmCalo"), - iConfig.getParameter("nMu"), - iConfig.getUntrackedParameter("debug_tk"), - iConfig.getUntrackedParameter("debug_calo"), - iConfig.getUntrackedParameter("debug_emcalo"), - iConfig.getUntrackedParameter("debug_mu") - ) { - debug_ = iConfig.getUntrackedParameter("debug"); -} - -edm::ParameterSetDescription l1ct::TDRAltRegionizerEmulator::getParameterSetDescription() { - edm::ParameterSetDescription description; - description.add("nTrack", 22); - description.add("nCalo", 15); - description.add("nEmCalo", 12); - description.add("nMu", 2); - description.addUntracked("debug", false); - description.addUntracked("debug_tk", false); - description.addUntracked("debug_calo", false); - description.addUntracked("debug_emcalo", false); - description.addUntracked("debug_mu", false); - return description; -} -#endif - -l1ct::TDRAltRegionizerEmulator::TDRAltRegionizerEmulator(uint32_t ntk, - uint32_t ncalo, - uint32_t nem, - uint32_t nmu, - bool debug_tk, - bool debug_calo, - bool debug_emcalo, - bool debug_mu - ) - : RegionizerEmulator(), - ntk_(ntk), - ncalo_(ncalo), - nem_(nem), - nmu_(nmu), - init_(false), - tkRegionizers_(ntk, debug_tk), - hadCaloRegionizers_(ncalo, debug_calo), - emCaloRegionizers_(nem, debug_emcalo), - muRegionizers_(nmu, debug_mu) {} - -l1ct::TDRAltRegionizerEmulator::~TDRAltRegionizerEmulator() {} - -void l1ct::TDRAltRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, - const std::vector& out) { - if (debug_) { - dbgCout() << "doing init, out_size = " << out.size() << std::endl; - } - assert(!init_); - init_ = true; - - - if (debug_) { - dbgCout() << "in.track.size() = " << in.track.size() << std::endl; - dbgCout() << "in.hadcalo.size() = " << in.hadcalo.size() << std::endl; - dbgCout() << "in.emcalo.size() = " << in.emcalo.size() << std::endl; - } - - tkRegionizers_.initSectors(in.track); - tkRegionizers_.initRegions(out); - hadCaloRegionizers_.initSectors(in.hadcalo); - hadCaloRegionizers_.initRegions(out); - emCaloRegionizers_.initSectors(in.emcalo); - emCaloRegionizers_.initRegions(out); - muRegionizers_.initSectors(in.muon); - muRegionizers_.initRegions(out); -} - -void l1ct::TDRAltRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { - if (debug_) { - dbgCout() << "TDRAltRegionizerEmulator::run called, out.size = " << out.size() << std::endl; - } - - if (!init_) { - initSectorsAndRegions(in, out); - } - - //add objects from link - tkRegionizers_.fillBuffers(in.track); - tkRegionizers_.run(); - - emCaloRegionizers_.fillBuffers(in.emcalo); - emCaloRegionizers_.run(); - - hadCaloRegionizers_.fillBuffers(in.hadcalo); - hadCaloRegionizers_.run(); - - muRegionizers_.fillBuffers(in.muon); - muRegionizers_.run(); - - - auto trackSRs = tkRegionizers_.smallRegions(); - auto emCaloSRs = emCaloRegionizers_.smallRegions(); - auto hadCaloSRs = hadCaloRegionizers_.smallRegions(); - auto muSRs = muRegionizers_.smallRegions(); - - for (size_t sr = 0; sr < trackSRs.size(); sr++) { - out[sr].track = trackSRs[sr]; - out[sr].emcalo = emCaloSRs[sr]; - out[sr].hadcalo = hadCaloSRs[sr]; - out[sr].muon = muSRs[sr]; - } - - tkRegionizers_.clearSmallRegions(); - emCaloRegionizers_.clearSmallRegions(); - hadCaloRegionizers_.clearSmallRegions(); - muRegionizers_.clearSmallRegions(); -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp index ca8d91f3461e5..c5b9d3155f4ff 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp @@ -12,26 +12,24 @@ l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(const edm::ParameterSet& iCon iConfig.getParameter("nCalo"), iConfig.getParameter("nEmCalo"), iConfig.getParameter("nMu"), - iConfig.getParameter("nClocks"), - iConfig.getParameter>("bigRegionEdges"), - iConfig.getParameter("netaInBR"), - iConfig.getParameter("nphiInBR"), - iConfig.getParameter("doSort")) { + iConfig.getUntrackedParameter("debug_tk"), + iConfig.getUntrackedParameter("debug_calo"), + iConfig.getUntrackedParameter("debug_emcalo"), + iConfig.getUntrackedParameter("debug_mu")) { debug_ = iConfig.getUntrackedParameter("debug"); } edm::ParameterSetDescription l1ct::TDRRegionizerEmulator::getParameterSetDescription() { edm::ParameterSetDescription description; - description.add("nClocks", 162); description.add("nTrack", 22); description.add("nCalo", 15); description.add("nEmCalo", 12); description.add("nMu", 2); - description.add("doSort", false); - description.add>("bigRegionEdges", {-560, -560}); - description.add("netaInBR", 6); - description.add("nphiInBR", 9); description.addUntracked("debug", false); + description.addUntracked("debug_tk", false); + description.addUntracked("debug_calo", false); + description.addUntracked("debug_emcalo", false); + description.addUntracked("debug_mu", false); return description; } #endif @@ -40,24 +38,20 @@ l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(uint32_t ntk, uint32_t ncalo, uint32_t nem, uint32_t nmu, - uint32_t nclocks, - std::vector bigRegionEdges, - uint32_t netaInBR, - uint32_t nphiInBR, - bool dosort) + bool debug_tk, + bool debug_calo, + bool debug_emcalo, + bool debug_mu) : RegionizerEmulator(), ntk_(ntk), ncalo_(ncalo), nem_(nem), nmu_(nmu), - nclocks_(nclocks), - bigRegionEdges_(bigRegionEdges), - dosort_(dosort), - netaInBR_(netaInBR), - nphiInBR_(nphiInBR), - init_(false) { - nBigRegions_ = bigRegionEdges_.size() - 1; -} + init_(false), + tkRegionizers_(ntk, debug_tk), + hadCaloRegionizers_(ncalo, debug_calo), + emCaloRegionizers_(nem, debug_emcalo), + muRegionizers_(nmu, debug_mu) {} l1ct::TDRRegionizerEmulator::~TDRRegionizerEmulator() {} @@ -65,52 +59,24 @@ void l1ct::TDRRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedI const std::vector& out) { if (debug_) { dbgCout() << "doing init, out_size = " << out.size() << std::endl; - dbgCout() << "nBigRegions_ = " << nBigRegions_ << std::endl; } assert(!init_); init_ = true; - for (unsigned int i = 0; i < nBigRegions_; i++) { - tkRegionizers_.emplace_back( - netaInBR_, nphiInBR_, ntk_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); - hadCaloRegionizers_.emplace_back( - netaInBR_, nphiInBR_, ncalo_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); // TM6 - emCaloRegionizers_.emplace_back( - netaInBR_, nphiInBR_, nem_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); // TM6 - muRegionizers_.emplace_back( - netaInBR_, nphiInBR_, nmu_, bigRegionEdges_[i], bigRegionEdges_[i + 1], nclocks_, 1, false); - } - if (debug_) { dbgCout() << "in.track.size() = " << in.track.size() << std::endl; dbgCout() << "in.hadcalo.size() = " << in.hadcalo.size() << std::endl; dbgCout() << "in.emcalo.size() = " << in.emcalo.size() << std::endl; } - if (ntk_) { - for (unsigned int i = 0; i < nBigRegions_; i++) { - tkRegionizers_[i].initSectors(in.track); - tkRegionizers_[i].initRegions(out); - } - } - if (ncalo_) { - for (unsigned int i = 0; i < nBigRegions_; i++) { - hadCaloRegionizers_[i].initSectors(in.hadcalo); - hadCaloRegionizers_[i].initRegions(out); - } - } - if (nem_) { - for (unsigned int i = 0; i < nBigRegions_; i++) { - emCaloRegionizers_[i].initSectors(in.emcalo); - emCaloRegionizers_[i].initRegions(out); - } - } - if (nmu_) { - for (unsigned int i = 0; i < nBigRegions_; i++) { - muRegionizers_[i].initSectors(in.muon); - muRegionizers_[i].initRegions(out); - } - } + tkRegionizers_.initSectors(in.track); + tkRegionizers_.initRegions(out); + hadCaloRegionizers_.initSectors(in.hadcalo); + hadCaloRegionizers_.initRegions(out); + emCaloRegionizers_.initSectors(in.emcalo); + emCaloRegionizers_.initRegions(out); + muRegionizers_.initSectors(in.muon); + muRegionizers_.initRegions(out); } void l1ct::TDRRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { @@ -122,41 +88,33 @@ void l1ct::TDRRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::ve initSectorsAndRegions(in, out); } - for (unsigned int ie = 0; ie < nBigRegions_; ie++) { - //add objects from link - tkRegionizers_[ie].reset(); - tkRegionizers_[ie].fillBuffers(in.track); - tkRegionizers_[ie].run(); + //add objects from link + tkRegionizers_.fillBuffers(in.track); + tkRegionizers_.run(); - emCaloRegionizers_[ie].reset(); - emCaloRegionizers_[ie].fillBuffers(in.emcalo); - emCaloRegionizers_[ie].run(); + emCaloRegionizers_.fillBuffers(in.emcalo); + emCaloRegionizers_.run(); - hadCaloRegionizers_[ie].reset(); - hadCaloRegionizers_[ie].fillBuffers(in.hadcalo); - hadCaloRegionizers_[ie].run(); + hadCaloRegionizers_.fillBuffers(in.hadcalo); + hadCaloRegionizers_.run(); - muRegionizers_[ie].reset(); - muRegionizers_[ie].fillBuffers(in.muon); - muRegionizers_[ie].run(); - } + muRegionizers_.fillBuffers(in.muon); + muRegionizers_.run(); - for (unsigned int ie = 0; ie < nBigRegions_; ie++) { - auto regionTrackMap = tkRegionizers_[ie].fillRegions(dosort_); - for (auto& pr : regionTrackMap) { - out[pr.first].track = pr.second; - } - auto regionEmCaloMap = emCaloRegionizers_[ie].fillRegions(dosort_); - for (auto& pr : regionEmCaloMap) { - out[pr.first].emcalo = pr.second; - } - auto regionHadCaloMap = hadCaloRegionizers_[ie].fillRegions(dosort_); - for (auto& pr : regionHadCaloMap) { - out[pr.first].hadcalo = pr.second; - } - auto regionMuMap = muRegionizers_[ie].fillRegions(dosort_); - for (auto& pr : regionMuMap) { - out[pr.first].muon = pr.second; - } + auto trackSRs = tkRegionizers_.smallRegions(); + auto emCaloSRs = emCaloRegionizers_.smallRegions(); + auto hadCaloSRs = hadCaloRegionizers_.smallRegions(); + auto muSRs = muRegionizers_.smallRegions(); + + for (size_t sr = 0; sr < trackSRs.size(); sr++) { + out[sr].track = trackSRs[sr]; + out[sr].emcalo = emCaloSRs[sr]; + out[sr].hadcalo = hadCaloSRs[sr]; + out[sr].muon = muSRs[sr]; } + + tkRegionizers_.clearSmallRegions(); + emCaloRegionizers_.clearSmallRegions(); + hadCaloRegionizers_.clearSmallRegions(); + muRegionizers_.clearSmallRegions(); } From 2eb214034d8ccba2bc97855567f886c776a488f8 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 27 Feb 2026 15:33:38 -0600 Subject: [PATCH 36/92] Changed mainly debug output, add tentative SR ordering (not verified) --- .../regionizer/tdr_regionizer_elements_ref.h | 3 +- .../tdr_regionizer_elements_ref.icc | 37 +++++++++++++++---- .../python/l1ctLayer1_patternWriters_cff.py | 6 ++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index 076208a89185e..7f944f945c68c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -35,6 +35,7 @@ namespace l1ct { //T obj() { return obj_; } const T& obj() const { return obj_; } + T& obj() { return obj_; } private: T obj_; @@ -114,7 +115,7 @@ namespace l1ct { void setBuffers(const std::vector>&& objvecvec); /// 'put' object in small region. The sr is physics - void addToSmallRegion(size_t sr, BufferEntry&& bufEntry); + void addToSmallRegion(size_t sr, BufferEntry bufEntry); /// returns 2D arrays, sectors (links) first dimension, objects second std::vector> fillLinks(const std::vector>& sectors) const; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index 8163c6749c988..f34bfef29b9e0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -28,6 +28,7 @@ inline bool l1ct::tdr_regionizer::Buffer::empty(size_t sr) const { } } +// Note: This assumes there's an entry. May need to check with empty (above) first. template inline l1ct::tdr_regionizer::BufferEntry l1ct::tdr_regionizer::Buffer::getEntry(size_t sr) { BufferEntry entry = data_[sr].front(); @@ -239,10 +240,19 @@ void l1ct::tdr_regionizer::Regionizer::setBuffers(const std::vector::setBuffers(const std::vector -void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntry&& bufEntry) { +void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntry bufEntry) { auto rawObj = bufEntry.obj(); // in small region, the relative eta and phi are based on a different center, so need to update @@ -263,6 +273,12 @@ void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntr rawObj.hwEta = locEta; rawObj.hwPhi = locPhi; + if (debug_) { + dbgCout() << "smallRegionObjects_ " << sr << " obj with pt = " << rawObj.intPt() << ", loc eta = " << rawObj.intEta() + << ", loc phi = " << rawObj.intPhi() << std::endl; + } + + smallRegionObjects_[sr].push_back(rawObj); } @@ -384,7 +400,12 @@ void l1ct::tdr_regionizer::Regionizer::run() { auto& buffer = buffers_[sectorMapLogToPhys_[link]]; if (!buffer.empty(sr)) { allEmpty = false; - addToSmallRegion(physSR, buffer.getEntry(sr)); + auto entry = buffer.getEntry(sr); + if (debug_) { + dbgCout() << "Adding to sr " << sr << " (physSR = " << physSR << ") obj with pt = " << entry.pt() << ", glb eta = " << entry.glbEta() + << ", glb phi = " << entry.glbPhi() << std::endl; + } + addToSmallRegion(physSR, entry); } } } while (!allEmpty); @@ -411,7 +432,7 @@ void l1ct::tdr_regionizer::Regionizer::clearSmallRegions() { template void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl; - dbgCout() << count << "\tbuffer\tphysreg\titem\tpt\teta\tphi\t" << std::endl; + dbgCout() << count << "\tbuffer\tlogreg\titem\tpt\teta\tphi\t" << std::endl; for (size_t logSector = 0; logSector < sectorMapLogToPhys_.size(); logSector++) { auto physSector = sectorMapLogToPhys_[logSector]; buffers_[physSector].printDebug(physSector, logSector); @@ -423,10 +444,10 @@ void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { auto physRegIdx = regionIndex(region); auto etaC = regions_[physRegIdx].intEtaCenter(); auto phiC = regions_[physRegIdx].intPhiCenter(); - for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) { - dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t" << physRegIdx << "\t" - << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t" - << smallRegionObjects_[region][j].intPhi() << std::endl; + for (unsigned int j = 0; j < smallRegionObjects_[physRegIdx].size(); j++) { + dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t\t" << physRegIdx << "\t" << j << "\t" + << smallRegionObjects_[physRegIdx][j].intPt() << "\t" << smallRegionObjects_[physRegIdx][j].intEta() << "\t" + << smallRegionObjects_[physRegIdx][j].intPhi() << std::endl; } dbgCout() << "-------------------------------" << std::endl; } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 5baad18dd265f..8cea5e076b4c4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -6,6 +6,10 @@ ##################################################################################################################### ## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now + +srOrder = (24, 30, 36, 42, 48, 0, 6, 12, 18, 25, 31, 37, 43, 49, 1, 7, 13, 19, 26, 32, 38, 44, 50, 2, 8, 14, 20, + 27, 33, 39, 45, 51, 3, 9, 15, 21, 28, 34, 40, 46, 52, 4, 10, 16, 22, 29, 35, 41, 47, 53, 5, 11, 17, 23) + _barrelWriterOutputOnly = cms.PSet( partition = cms.string("Barrel"), tmuxFactor = cms.uint32(18), @@ -29,7 +33,7 @@ gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), tfNumberOfTracks = cms.uint32(108), gctNumberOfObjects = cms.uint32(162), - outputRegions = cms.vuint32(*range(54)), + outputRegions = cms.vuint32(*srOrder), outputBoard = cms.int32(0), ) ## Barrel (54) split in 3 phi slices (EMP format) From 18d4b0e0616c8ec575b867d99d536f23adce6297 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 2 Mar 2026 15:11:02 -0600 Subject: [PATCH 37/92] Swap slr3 and slr1 mapping to phi, switch to returning physical links --- .../regionizer/tdr_regionizer_elements_ref.h | 2 +- .../tdr_regionizer_elements_ref.icc | 43 ++++++++++--------- .../plugins/L1TCorrelatorLayer1Producer.cc | 22 +++++----- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index 7f944f945c68c..9594103522f76 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -102,7 +102,7 @@ namespace l1ct { /// @return pair (eta, phi) region index) std::pair get_small_region(size_t sr) const; - /// logical links associated with a logical sr (customized for each type) + /// physical links associated with a logical sr (customized for each type) std::vector linksForSR(size_t sr) const; std::vector caloLinksHelper(size_t iphi) const; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index f34bfef29b9e0..c64fe9a24d5f0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -290,6 +290,7 @@ inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_ return retval; } +// returns the physical links template <> inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { std::pair logic_sr = get_small_region(sr); @@ -300,52 +301,52 @@ inline std::vector l1ct::tdr_regionizer::Regionizer::lin auto nom = iphi; auto smaller = (nom == 0) ? 8 : nom - 1; auto bigger = (nom == 8) ? 0 : nom + 1; - retval.push_back(nom); - retval.push_back(smaller); - retval.push_back(bigger); + retval.push_back(sectorMapLogToPhys_[nom]); + retval.push_back(sectorMapLogToPhys_[smaller]); + retval.push_back(sectorMapLogToPhys_[bigger]); if (ieta == 2) { // also add the other ones - retval.push_back(nom + 9); - retval.push_back(smaller + 9); - retval.push_back(bigger + 9); + retval.push_back(sectorMapLogToPhys_[nom + 9]); + retval.push_back(sectorMapLogToPhys_[smaller + 9]); + retval.push_back(sectorMapLogToPhys_[bigger + 9]); } } else { auto nom = iphi + 9; auto smaller = (nom == 9) ? 17 : nom - 1; auto bigger = (nom == 17) ? 9 : nom + 1; - retval.push_back(nom); - retval.push_back(smaller); - retval.push_back(bigger); + retval.push_back(sectorMapLogToPhys_[nom]); + retval.push_back(sectorMapLogToPhys_[smaller]); + retval.push_back(sectorMapLogToPhys_[bigger]); if (ieta == 3) { // also add the other ones - retval.push_back(nom - 9); - retval.push_back(smaller - 9); - retval.push_back(bigger - 9); + retval.push_back(sectorMapLogToPhys_[nom - 9]); + retval.push_back(sectorMapLogToPhys_[smaller - 9]); + retval.push_back(sectorMapLogToPhys_[bigger - 9]); } } return retval; } -// slighlty more complicated because of logical index; +// Note that these are phyisical links template inline std::vector l1ct::tdr_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { if (iphi < 2) { - std::vector retval = {11, 5, 6, 0, 7, 1, 8, 2}; + std::vector retval = {9, 3, 8, 2, 11, 5, 10, 4}; return retval; } else if (iphi < 3) { - std::vector retval = {7, 1, 8, 2}; + std::vector retval = {11, 5, 10, 4}; return retval; } else if (iphi < 5) { - std::vector retval = {9, 3, 10, 4, 7, 1, 8, 2}; + std::vector retval = {11, 5, 10, 4, 7, 1, 6, 0}; return retval; } else if (iphi < 6) { - std::vector retval = {9, 3, 10, 4}; + std::vector retval = {7, 1, 6, 0}; return retval; } else if (iphi < 8) { - std::vector retval = {9, 3, 10, 4, 11, 5, 6, 0}; + std::vector retval = {7, 1, 6, 0, 9, 3, 8, 2}; return retval; } else { - std::vector retval = {11, 5, 6, 0}; + std::vector retval = {9, 3, 8, 2}; return retval; } } @@ -391,13 +392,13 @@ void l1ct::tdr_regionizer::Regionizer::run() { for (size_t sr = 0; sr < regionmap_.size(); sr++) { // iterate over the (logical) SRs - auto links = linksForSR(sr); // these are the logical links + auto links = linksForSR(sr); // these are the physical links auto physSR = regionmap_[sr]; bool allEmpty; do { allEmpty = true; for (auto link : links) { - auto& buffer = buffers_[sectorMapLogToPhys_[link]]; + auto& buffer = buffers_[link]; if (!buffer.empty(sr)) { allEmpty = false; auto entry = buffer.getEntry(sr); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index e969d8e8b6475..bbf7b1701491e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -1013,31 +1013,31 @@ void L1TCorrelatorLayer1Producer::addHGCalHadCalo(const l1t::HGCalMulticluster & // The raw to decoded index mapping is // raw -> eta+ slr1 eta- slr1 eta+ slr3 eta1 slr3 -// 0 6 0 7 1 -// 1 8 2 9 3 -// 2 10 4 11 5 +// 0 7 1 6 0 +// 1 9 3 8 2 +// 2 11 5 10 4 unsigned int L1TCorrelatorLayer1Producer::emDecodedIndex(unsigned int linkidx, unsigned int entidx) const { if (entidx < 17) { - return 2 * linkidx + 6; + return 2 * linkidx + 7; } else if (entidx < 81) { - return 2 * linkidx; + return 2 * linkidx + 1; } else if (entidx < 98) { - return 2 * linkidx + 7; + return 2 * linkidx + 6; } else { - return 2 * linkidx + 1; + return 2 * linkidx; } } unsigned int L1TCorrelatorLayer1Producer::hadDecodedIndex(unsigned int linkidx, unsigned int entidx) const { if (entidx < 57) { - return 2 * linkidx + 6; + return 2 * linkidx + 7; } else if (entidx < 81) { - return 2 * linkidx; + return 2 * linkidx + 1; } else if (entidx < 138) { - return 2 * linkidx + 7; + return 2 * linkidx + 6; } else { - return 2 * linkidx + 1; + return 2 * linkidx; } } From ba87280f2a2f445f38ba1b93e0fce78efbf76cd7 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 2 Mar 2026 16:08:06 -0600 Subject: [PATCH 38/92] minor fixes for pattern writer --- .../regionizer/tdr_regionizer_elements_ref.icc | 13 ++++++------- .../src/L1TCorrelatorLayer1PatternFileWriter.cc | 15 +++++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index c64fe9a24d5f0..c5eb49216867c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -274,11 +274,10 @@ void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntr rawObj.hwPhi = locPhi; if (debug_) { - dbgCout() << "smallRegionObjects_ " << sr << " obj with pt = " << rawObj.intPt() << ", loc eta = " << rawObj.intEta() - << ", loc phi = " << rawObj.intPhi() << std::endl; + dbgCout() << "smallRegionObjects_ " << sr << " obj with pt = " << rawObj.intPt() + << ", loc eta = " << rawObj.intEta() << ", loc phi = " << rawObj.intPhi() << std::endl; } - smallRegionObjects_[sr].push_back(rawObj); } @@ -403,8 +402,8 @@ void l1ct::tdr_regionizer::Regionizer::run() { allEmpty = false; auto entry = buffer.getEntry(sr); if (debug_) { - dbgCout() << "Adding to sr " << sr << " (physSR = " << physSR << ") obj with pt = " << entry.pt() << ", glb eta = " << entry.glbEta() - << ", glb phi = " << entry.glbPhi() << std::endl; + dbgCout() << "Adding to sr " << sr << " (physSR = " << physSR << ") obj with pt = " << entry.pt() + << ", glb eta = " << entry.glbEta() << ", glb phi = " << entry.glbPhi() << std::endl; } addToSmallRegion(physSR, entry); } @@ -447,8 +446,8 @@ void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { auto phiC = regions_[physRegIdx].intPhiCenter(); for (unsigned int j = 0; j < smallRegionObjects_[physRegIdx].size(); j++) { dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t\t" << physRegIdx << "\t" << j << "\t" - << smallRegionObjects_[physRegIdx][j].intPt() << "\t" << smallRegionObjects_[physRegIdx][j].intEta() << "\t" - << smallRegionObjects_[physRegIdx][j].intPhi() << std::endl; + << smallRegionObjects_[physRegIdx][j].intPt() << "\t" << smallRegionObjects_[physRegIdx][j].intEta() + << "\t" << smallRegionObjects_[physRegIdx][j].intPhi() << std::endl; } dbgCout() << "-------------------------------" << std::endl; } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 9e9d7b1eb9180..a952512d0157a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -4,6 +4,7 @@ #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/ParameterSet/interface/allowedValues.h" #include +#include L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const edm::ParameterSet& iConfig, const l1ct::Event& eventTemplate) @@ -460,7 +461,11 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, // Note: the writers have a width of 64 very much hardcoded in the sizes. Therefore, send the 73 bits as // two separate "fibers" - constexpr unsigned int MAX_BITWIDTH = 73; // Should be the biggest object width (or greater) + constexpr unsigned int MAX_BITWIDTH = + std::max({l1ct::TkObjEmu::BITWIDTH_BARREL, + l1ct::EmCaloObjEmu::BITWIDTH_BARREL, + l1ct::HadCaloObjEmu::BITWIDTH_BARREL, + l1ct::MuObjEmu::BITWIDTH}); // Should be the biggest object width (or greater) if (nPFInTrack_) { std::vector>> linksLow(nPFInTrack_); // virtual links -- bits 63:0 @@ -469,7 +474,7 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, auto pfvals = event.pfinputs[ir].track; unsigned int npfvals = pfvals.size(); for (unsigned int i = 0; i < nPFInTrack_; ++i) { - ap_uint val = i < npfvals ? pfvals[i].pack() : ap_uint(0); + ap_uint val = i < npfvals ? pfvals[i].pack_barrel() : ap_uint(0); linksHigh[i].push_back(val(MAX_BITWIDTH - 1, 64)); linksLow[i].push_back(val(63, 0)); } @@ -486,7 +491,8 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, auto pfvals = event.pfinputs[ir].emcalo; unsigned int npfvals = pfvals.size(); for (unsigned int i = 0; i < nPFInEmCalo_; ++i) { - ap_uint val = i < npfvals ? pfvals[i].pack() : ap_uint(0); + ap_uint val = + i < npfvals ? pfvals[i].pack_barrel() : ap_uint(0); linksHigh[i].push_back(val(MAX_BITWIDTH - 1, 64)); linksLow[i].push_back(val(63, 0)); } @@ -503,7 +509,8 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, auto pfvals = event.pfinputs[ir].hadcalo; unsigned int npfvals = pfvals.size(); for (unsigned int i = 0; i < nPFInHadCalo_; ++i) { - ap_uint val = i < npfvals ? pfvals[i].pack() : ap_uint(0); + ap_uint val = + i < npfvals ? pfvals[i].pack_barrel() : ap_uint(0); linksHigh[i].push_back(val(MAX_BITWIDTH - 1, 64)); linksLow[i].push_back(val(63, 0)); } From 07363311141b5e7904970d2f4c2669eae49e2923 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 12 Mar 2026 11:36:37 -0500 Subject: [PATCH 39/92] fix output order of pattern files--was using map in the wrong direction --- .../interface/regionizer/tdr_regionizer_elements_ref.icc | 5 +++-- .../python/l1ctLayer1_patternWriters_cff.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index c5eb49216867c..75bf47b044f37 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -440,14 +440,15 @@ void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { dbgCout() << "SMALL REGIONS" << std::endl; for (unsigned int region = 0; region < regionmap_.size(); region++) { - dbgCout() << count << "\tregion\t\tphysRegion\titem\tpt\tloceta\tlocphi" << std::endl; + dbgCout() << count << "\tregion\t\tphysRegion\titem\tpt\tloceta\tlocphi\tpacked" << std::endl; auto physRegIdx = regionIndex(region); auto etaC = regions_[physRegIdx].intEtaCenter(); auto phiC = regions_[physRegIdx].intPhiCenter(); for (unsigned int j = 0; j < smallRegionObjects_[physRegIdx].size(); j++) { dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t\t" << physRegIdx << "\t" << j << "\t" << smallRegionObjects_[physRegIdx][j].intPt() << "\t" << smallRegionObjects_[physRegIdx][j].intEta() - << "\t" << smallRegionObjects_[physRegIdx][j].intPhi() << std::endl; + << "\t" << smallRegionObjects_[physRegIdx][j].intPhi() + << "\t" << smallRegionObjects_[physRegIdx][j].pack().to_string(16) << std::endl; } dbgCout() << "-------------------------------" << std::endl; } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 8cea5e076b4c4..74ad6e7e82aa3 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -7,8 +7,8 @@ ##################################################################################################################### ## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now -srOrder = (24, 30, 36, 42, 48, 0, 6, 12, 18, 25, 31, 37, 43, 49, 1, 7, 13, 19, 26, 32, 38, 44, 50, 2, 8, 14, 20, - 27, 33, 39, 45, 51, 3, 9, 15, 21, 28, 34, 40, 46, 52, 4, 10, 16, 22, 29, 35, 41, 47, 53, 5, 11, 17, 23) +srOrder = (5, 14, 23, 32, 41, 50, 6, 15, 24, 33, 42, 51, 7, 16, 25, 34, 43, 52, 8, 17, 26, 35, 44, 53, 0, 9, 18, + 27, 36, 45, 1, 10, 19, 28, 37, 46, 2, 11, 20, 29, 38, 47, 3, 12, 21, 30, 39, 48, 4, 13, 22, 31, 40, 49) _barrelWriterOutputOnly = cms.PSet( partition = cms.string("Barrel"), From 5ac38f3ec4ab21db4fb01bc8c58d13def297068c Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 12 Mar 2026 19:31:17 -0500 Subject: [PATCH 40/92] add pt=0 throwout matching to how it's done in the firmware --- .../interface/regionizer/tdr_regionizer_elements_ref.icc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index 75bf47b044f37..e265baab99ef1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -242,8 +242,8 @@ void l1ct::tdr_regionizer::Regionizer::setBuffers(const std::vector Date: Fri, 13 Mar 2026 17:06:50 -0500 Subject: [PATCH 41/92] update GCT converter emulation --- .../src/l1-converters/gcteminput_ref.cpp | 7 ++++++- .../src/l1-converters/gcthadinput_ref.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index c9d4a98bb198e..35da67298aee0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -47,7 +47,6 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio calo.hwPt = l1ct::Scales::makePtFromFloat(newpt); } - // Note: at this point still calo.hwPtErr = l1ct::Scales::makePtFromFloat(resol_(calo.floatPt(), calo.floatEta())); // NOTE: this is still abs(globalEta) @@ -56,6 +55,12 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio // bit 1: looseL1TkMatchWP: is_looseTkiso && is_looseTkss // bit 2: photonWP: calo.hwEmID = inclus.wp(); + + // Should any of these values be corrected? At the moment they are not + calo.hwRelIso = l1ct::Scales::makeRelIso(inclus.iso() * inclus.ptLSB() / inclus.ptFloat()); + + calo.hwShowerShape = inclus.shape(); + // convert eta to local if (sector.hwEtaCenter < 0) { calo.hwEta = -calo.hwEta - sector.hwEtaCenter; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index be38da378599d..043e2808d8506 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -31,7 +31,7 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); // need to add emid, default to zero for had/PF clusters from GCT - calo.hwEmID = 0; + calo.hwEmID = inclus.fb(); // convert eta to local if (sector.hwEtaCenter < 0) { From d567f5f6a74f82cdef7ff51c3b559d940705ff27 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Sun, 15 Mar 2026 13:42:38 -0500 Subject: [PATCH 42/92] add a divide by 0 catch for relative iso --- .../src/l1-converters/gcteminput_ref.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index 35da67298aee0..0a47296412199 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -56,8 +56,10 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio // bit 2: photonWP: calo.hwEmID = inclus.wp(); - // Should any of these values be corrected? At the moment they are not - calo.hwRelIso = l1ct::Scales::makeRelIso(inclus.iso() * inclus.ptLSB() / inclus.ptFloat()); + // Should any of these values be corrected? Choose corrected pt, uncorrected iso energy + calo.hwRelIso = (calo.hwPt > 0) ? + l1ct::Scales::makeRelIso(inclus.iso() * inclus.ptLSB() / calo.floatPt()) : + static_cast(0); calo.hwShowerShape = inclus.shape(); From 7ec6762977f6ffd208219b6452aa097085ad8f58 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 17 Mar 2026 19:04:42 -0500 Subject: [PATCH 43/92] fix relative iso for GCT EM clusters --- .../plugins/L1TCorrelatorLayer1Producer.cc | 6 ------ .../src/l1-converters/gcteminput_ref.cpp | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index bbf7b1701491e..11b47720b7cdd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -803,12 +803,6 @@ void L1TCorrelatorLayer1Producer::addDecodedEmCalo(l1ct::EmCaloObjEmu &decCalo, l1ct::DetectorSector &sec) { clusterRefMap_[caloPtr.get()] = caloPtr; decCalo.src = caloPtr.get(); - if (decCalo.hwPt > 0) { // NOTE: 0 pt clusters have null ptr. Do we need to keep them? - // FIXME: for now we extract these from the upstream object since they are not yet available in the digi format - const l1tp2::CaloCrystalCluster *crycl = dynamic_cast(decCalo.src); - decCalo.hwShowerShape = l1ct::shower_shape_t(crycl->e2x5() / crycl->e5x5()); - decCalo.hwRelIso = l1ct::Scales::makeRelIso(crycl->isolation() / decCalo.hwPt.to_float()); - } sec.obj.push_back(decCalo); } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index 0a47296412199..26cca133d1e04 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -58,7 +58,7 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio // Should any of these values be corrected? Choose corrected pt, uncorrected iso energy calo.hwRelIso = (calo.hwPt > 0) ? - l1ct::Scales::makeRelIso(inclus.iso() * inclus.ptLSB() / calo.floatPt()) : + static_cast(inclus.iso() * inclus.ptLSB() / calo.floatPt()) : static_cast(0); calo.hwShowerShape = inclus.shape(); From 958a942865b78395cc1e1b68a587332e947406f3 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 18 Mar 2026 12:27:57 -0500 Subject: [PATCH 44/92] update gct em converter emulaiton --- .../src/l1-converters/gcteminput_ref.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index 26cca133d1e04..a1d862132ce8c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -56,12 +56,9 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio // bit 2: photonWP: calo.hwEmID = inclus.wp(); - // Should any of these values be corrected? Choose corrected pt, uncorrected iso energy - calo.hwRelIso = (calo.hwPt > 0) ? - static_cast(inclus.iso() * inclus.ptLSB() / calo.floatPt()) : - static_cast(0); - - calo.hwShowerShape = inclus.shape(); + // Copying the bits directly. + calo.hwRelIso(rel_iso_t::width-1, 0) = inclus.iso()(rel_iso_t::width-1, 0); + calo.hwShowerShape(shower_shape_t::width-1, 0) = inclus.shape()(shower_shape_t::width-1, 0); // convert eta to local if (sector.hwEtaCenter < 0) { From 137b5a47b295f48bd08652e41d8a7e6ab76ba9b9 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 20 Mar 2026 13:51:26 -0500 Subject: [PATCH 45/92] model virtual fibers on one physical fiber "bundle" in emulation --- .../regionizer/tdr_regionizer_elements_ref.h | 6 +- .../tdr_regionizer_elements_ref.icc | 78 +++++++++++-------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index 9594103522f76..7787043efa24d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -103,8 +103,10 @@ namespace l1ct { std::pair get_small_region(size_t sr) const; /// physical links associated with a logical sr (customized for each type) - std::vector linksForSR(size_t sr) const; - std::vector caloLinksHelper(size_t iphi) const; + /// Note that these are grouped in bundles (to help model calo order) + std::vector> linksForSR(size_t sr) const; + std::vector> caloLinksHelper(size_t iphi) const; + void getNextIndex(size_t sr, const std::vector& bundle, size_t& nextIdx) const; unsigned int numBuffers() const { return buffers_.size(); } unsigned int numEntries(unsigned int bufferIndex) const { return buffers_[bufferIndex].numEntries(); } diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index e265baab99ef1..ab6a292f41ef0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -283,44 +283,44 @@ void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntr // This is a dummy, should never be used. template -inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { - std::vector retval; +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { + std::vector> retval; throw cms::Exception("LogicError") << "This should be customized per type."; return retval; } // returns the physical links template <> -inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { std::pair logic_sr = get_small_region(sr); const auto& ieta = logic_sr.first; const auto& iphi = logic_sr.second; - std::vector retval; + std::vector> retval; if (ieta < 3) { auto nom = iphi; auto smaller = (nom == 0) ? 8 : nom - 1; auto bigger = (nom == 8) ? 0 : nom + 1; - retval.push_back(sectorMapLogToPhys_[nom]); - retval.push_back(sectorMapLogToPhys_[smaller]); - retval.push_back(sectorMapLogToPhys_[bigger]); + retval.emplace_back(1, sectorMapLogToPhys_[nom]); + retval.emplace_back(1, sectorMapLogToPhys_[smaller]); + retval.emplace_back(1, sectorMapLogToPhys_[bigger]); if (ieta == 2) { // also add the other ones - retval.push_back(sectorMapLogToPhys_[nom + 9]); - retval.push_back(sectorMapLogToPhys_[smaller + 9]); - retval.push_back(sectorMapLogToPhys_[bigger + 9]); + retval.emplace_back(1, sectorMapLogToPhys_[nom + 9]); + retval.emplace_back(1, sectorMapLogToPhys_[smaller + 9]); + retval.emplace_back(1, sectorMapLogToPhys_[bigger + 9]); } } else { auto nom = iphi + 9; auto smaller = (nom == 9) ? 17 : nom - 1; auto bigger = (nom == 17) ? 9 : nom + 1; - retval.push_back(sectorMapLogToPhys_[nom]); - retval.push_back(sectorMapLogToPhys_[smaller]); - retval.push_back(sectorMapLogToPhys_[bigger]); + retval.emplace_back(1, sectorMapLogToPhys_[nom]); + retval.emplace_back(1, sectorMapLogToPhys_[smaller]); + retval.emplace_back(1, sectorMapLogToPhys_[bigger]); if (ieta == 3) { // also add the other ones - retval.push_back(sectorMapLogToPhys_[nom - 9]); - retval.push_back(sectorMapLogToPhys_[smaller - 9]); - retval.push_back(sectorMapLogToPhys_[bigger - 9]); + retval.emplace_back(1, sectorMapLogToPhys_[nom - 9]); + retval.emplace_back(1, sectorMapLogToPhys_[smaller - 9]); + retval.emplace_back(1, sectorMapLogToPhys_[bigger - 9]); } } return retval; @@ -328,43 +328,43 @@ inline std::vector l1ct::tdr_regionizer::Regionizer::lin // Note that these are phyisical links template -inline std::vector l1ct::tdr_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::caloLinksHelper(size_t iphi) const { if (iphi < 2) { - std::vector retval = {9, 3, 8, 2, 11, 5, 10, 4}; + std::vector> retval = {{9, 3, 8, 2}, {11, 5, 10, 4}}; return retval; } else if (iphi < 3) { - std::vector retval = {11, 5, 10, 4}; + std::vector> retval = {{11, 5, 10, 4}}; return retval; } else if (iphi < 5) { - std::vector retval = {11, 5, 10, 4, 7, 1, 6, 0}; + std::vector> retval = {{11, 5, 10, 4}, {7, 1, 6, 0}}; return retval; } else if (iphi < 6) { - std::vector retval = {7, 1, 6, 0}; + std::vector> retval = {{7, 1, 6, 0}}; return retval; } else if (iphi < 8) { - std::vector retval = {7, 1, 6, 0, 9, 3, 8, 2}; + std::vector> retval = {{7, 1, 6, 0}, {9, 3, 8, 2}}; return retval; } else { - std::vector retval = {9, 3, 8, 2}; + std::vector> retval = {{9, 3, 8, 2}}; return retval; } } template <> -inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { const std::pair logic_sr = get_small_region(sr); return caloLinksHelper(logic_sr.second); } template <> -inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { const std::pair logic_sr = get_small_region(sr); return caloLinksHelper(logic_sr.second); } template <> -inline std::vector l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { - std::vector retval = {0}; +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t) const { + std::vector> retval = {{0}}; return retval; } @@ -384,6 +384,19 @@ std::pair l1ct::tdr_regionizer::Regionizer::get_small_region( return rval; } +// Note that this also updates the index so that if if's not empty, you can directly access value +// One needs to check that the next index is not bundle.size() +template +void l1ct::tdr_regionizer::Regionizer::getNextIndex(size_t sr, const std::vector& bundle, size_t& nextIdx) const { + for (;nextIdx < bundle.size(); nextIdx++) { + auto& buffer = buffers_[bundle[nextIdx]]; + if (!buffer.empty(sr)) { + return; + } + } +} + + template void l1ct::tdr_regionizer::Regionizer::run() { if (debug_) @@ -391,14 +404,17 @@ void l1ct::tdr_regionizer::Regionizer::run() { for (size_t sr = 0; sr < regionmap_.size(); sr++) { // iterate over the (logical) SRs - auto links = linksForSR(sr); // these are the physical links + auto links = linksForSR(sr); // these are the physical links, in bundles + std::vector nextIndex(links.size(), 0); // this is per bundle auto physSR = regionmap_[sr]; bool allEmpty; do { allEmpty = true; - for (auto link : links) { - auto& buffer = buffers_[link]; - if (!buffer.empty(sr)) { + for (size_t bundleIdx = 0; bundleIdx < links.size(); bundleIdx++) { + getNextIndex(sr, links[bundleIdx], nextIndex[bundleIdx]); + if (nextIndex[bundleIdx] < links[bundleIdx].size()) { + // found a non-empty buffer in the bundle + auto& buffer = buffers_[links[bundleIdx][nextIndex[bundleIdx]]]; allEmpty = false; auto entry = buffer.getEntry(sr); if (debug_) { From f7c01650e4a80d4270c4a815887d82968e2e6859 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 26 Mar 2026 11:45:54 -0500 Subject: [PATCH 46/92] fix pattern file configuration (and obsolete comment in source code) --- .../python/l1ctLayer1_patternWriters_cff.py | 2 ++ .../src/L1TCorrelatorLayer1PatternFileWriter.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 74ad6e7e82aa3..16b492ddd96d5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -241,6 +241,7 @@ nPFInEmCalo = cms.uint32(12), nPFInHadCalo = cms.uint32(15), nPFInMuon = cms.uint32(2), + nOutputFramesPerBX = cms.uint32(3), #(18 * 2/3 (going to 240) * 1/2 (doing II = 2)) debugFileName = cms.string("l1BarrelApx-pfin") ) @@ -250,6 +251,7 @@ nPFOutPhoton = cms.uint32(12), nPFOutNeutral = cms.uint32(15), nPFOutMuon = cms.uint32(2), + nOutputFramesPerBX = cms.uint32(3), #(18 * 2/3 (going to 240) * 1/2 (doing II = 2)) debugFileName = cms.string("l1BarrelApx-pfout") ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index a952512d0157a..0be5a89dede86 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -458,7 +458,7 @@ void L1TCorrelatorLayer1PatternFileWriter::writeGTT(const l1ct::Event& event, l1 // Debug functions output internal data for debugging purposes, mainly emulation/simulation comparison void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, l1t::demo::EventData& out) { - // Note: the writers have a width of 64 very much hardcoded in the sizes. Therefore, send the 73 bits as + // Note: the writers have a width of 64 very much hardcoded in the sizes. Therefore, send the bits as // two separate "fibers" constexpr unsigned int MAX_BITWIDTH = From e6415e684af5ad2173fb64cbd63cd9567f66f242 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Thu, 19 Mar 2026 17:40:02 +0100 Subject: [PATCH 47/92] updates for rel iso and hoe, rename TMI18 to TM18 --- ...MI18.h => DigitizedCaloToCorrelatorTM18.h} | 12 ++-- .../L1TCalorimeterPhase2/src/classes.h | 2 +- .../L1TCalorimeterPhase2/src/classes_def.xml | 8 +-- .../interface/Phase2L1CaloEGammaUtils.h | 63 +++++++++---------- ...TMI18.h => Phase2L1CaloToCorrelatorTM18.h} | 6 +- ...I18.cc => Phase2L1CaloToCorrelatorTM18.cc} | 44 ++++++------- ...y => l1tPhase2CaloToCorrelatorTM18_cfi.py} | 2 +- .../plugins/L1TCorrelatorLayer1Producer.cc | 6 +- .../python/l1ctLayer1_cff.py | 2 +- .../test/make_l1ct_binaryFiles_cfg.py | 7 +-- 10 files changed, 74 insertions(+), 78 deletions(-) rename DataFormats/L1TCalorimeterPhase2/interface/{DigitizedCaloToCorrelatorTMI18.h => DigitizedCaloToCorrelatorTM18.h} (78%) rename L1Trigger/L1CaloTrigger/interface/{Phase2L1CaloToCorrelatorTMI18.h => Phase2L1CaloToCorrelatorTM18.h} (92%) rename L1Trigger/L1CaloTrigger/plugins/{Phase2L1CaloToCorrelatorTMI18.cc => Phase2L1CaloToCorrelatorTM18.cc} (88%) rename L1Trigger/L1CaloTrigger/python/{l1tPhase2CaloToCorrelatorTMI18_cfi.py => l1tPhase2CaloToCorrelatorTM18_cfi.py} (79%) diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h similarity index 78% rename from DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h rename to DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h index 2dd970bc6fd83..fbded5ce8c5ad 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h @@ -1,5 +1,5 @@ -#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTMI18_h -#define DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTMI18_h +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTM18_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTM18_h #include #include @@ -11,7 +11,7 @@ namespace l1tp2 { typedef std::variant GCTDigiCluster; typedef std::vector GCTDigiClusterLink; - class DigitizedCaloToCorrelatorTMI18 { + class DigitizedCaloToCorrelatorTM18 { private: // Data (to remove) ap_uint<64> CardData[162]; @@ -19,12 +19,12 @@ namespace l1tp2 { GCTDigiClusterLink CardLink; public: - DigitizedCaloToCorrelatorTMI18() { + DigitizedCaloToCorrelatorTM18() { for (int i = 0; i < 162; i++) { CardData[i] = 0; } } - DigitizedCaloToCorrelatorTMI18(ap_uint<64> data[162], GCTDigiClusterLink link) { + DigitizedCaloToCorrelatorTM18(ap_uint<64> data[162], GCTDigiClusterLink link) { for (int i = 0; i < 162; i++) { CardData[i] = data[i]; } @@ -37,7 +37,7 @@ namespace l1tp2 { // Collection typedef // this represents both the EM and PF clusters from a single GCT card in one link - typedef std::vector DigitizedCaloToCorrelatorCollectionTMI18; + typedef std::vector DigitizedCaloToCorrelatorCollectionTM18; } // namespace l1tp2 diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes.h b/DataFormats/L1TCalorimeterPhase2/src/classes.h index 8c5f5706e8966..0c9ef90a160bb 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes.h +++ b/DataFormats/L1TCalorimeterPhase2/src/classes.h @@ -19,4 +19,4 @@ #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/Phase2L1CaloJet.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h" diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml index 20b2fd217a8e0..96ab501c0039d 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml +++ b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml @@ -84,11 +84,11 @@ - - + + - - + + diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 2b42db69aa5b8..15e3b7c0cc42b 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1312,12 +1312,23 @@ namespace p2eg { ap_uint<3> quality = (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); + // normalize relIso to 0x3F + int relIso_int = 0; + if (et > iso && et > 0) { + relIso_int = (int)(iso * 63 / et); + } else { + relIso_int = 63; + } + + // normalize hoe to 0x3F + int hoe_int = (int)(hoe * 63 /15); + return l1tp2::DigitizedClusterCorrelator( et, // technically we are just multiplying and then dividing again by the LSB abseta, phivscenter, - ap_uint<6>(hoe & 0x3F), - ap_uint<6>(iso & 0x3F), + ap_uint<6>(hoe_int & 0x3F), + ap_uint<6>(relIso_int & 0x3F), ap_uint<6>(shape), ap_uint<3>(quality), ap_uint<5>(timing), @@ -1362,7 +1373,7 @@ namespace p2eg { class GCTtower_t { public: ap_uint<12> et; - ap_uint<4> hoe; + ap_uint<6> hoe; ap_uint<2> fb; // not defined yet in emulator // For CMSSW outputs, not firmware ap_uint<12> ecalEt; @@ -1383,41 +1394,27 @@ namespace p2eg { */ void initFromRCTTower(const RCTtower_t& rctTower) { et = rctTower.et; - hoe = rctTower.hoe; + int hoe_int = 0; + //hoe_int = (int)(rctTower.hoe * 63 / 15); // RCT hoe is 4 bits + hoe = hoe_int & 0x3F; ecalEt = rctTower.ecalEt; hcalEt = rctTower.hcalEt; + if (ecalEt > hcalEt && ecalEt > 0) { + hoe_int = (int)(hcalEt * 63 / ecalEt); + } else { + hoe_int = 63; + } + hoe = hoe_int & 0x3F; } - void addHoverEToTower(ap_uint<12> ECAL, ap_uint<12> HCAL) { - ap_uint<4> hoeOut = 0; - ap_uint<1> hoeLSB = 0; - ap_uint<12> A; - ap_uint<12> B; - - A = (ECAL > HCAL) ? ECAL : HCAL; - B = (ECAL > HCAL) ? HCAL : ECAL; - - if (ECAL == 0 || HCAL == 0 || HCAL >= ECAL) - hoeLSB = 0; - else - hoeLSB = 1; - if (A > B) { - if (A > 2 * B) - hoeOut = 0x1; - if (A > 4 * B) - hoeOut = 0x2; - if (A > 8 * B) - hoeOut = 0x3; - if (A > 16 * B) - hoeOut = 0x4; - if (A > 32 * B) - hoeOut = 0x5; - if (A > 64 * B) - hoeOut = 0x6; - if (A > 128 * B) - hoeOut = 0x7; + void addHoverEToTower(ap_uint<12> ecalEt, ap_uint<12> hcalEt) { + int hoe_int = 0; + if (ecalEt > hcalEt && ecalEt > 0) { + hoe_int = (int)(hcalEt * 63 / ecalEt); + } else { + hoe_int = 63; } - hoe = hoeLSB | (hoeOut << 1); + hoe = hoe_int & 0x3F; } /* diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h similarity index 92% rename from L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h rename to L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h index f6806bdb8192d..86b55016bb4f1 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h @@ -1,5 +1,5 @@ -#ifndef Phase2L1CaloToCorrelatorTMI18_H -#define Phase2L1CaloToCorrelatorTMI18_H +#ifndef Phase2L1CaloToCorrelatorTM18_H +#define Phase2L1CaloToCorrelatorTM18_H // system include files #include @@ -36,7 +36,7 @@ #include "FWCore/Framework/interface/ESHandle.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h" // // class declaration diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc similarity index 88% rename from L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc rename to L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc index 833aa9b57c246..0f01e5090c4a5 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTMI18.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc @@ -19,16 +19,16 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTMI18.h" +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h" -class Phase2L1CaloToCorrelatorTMI18 : public edm::stream::EDProducer<> { +class Phase2L1CaloToCorrelatorTM18 : public edm::stream::EDProducer<> { public: - explicit Phase2L1CaloToCorrelatorTMI18(const edm::ParameterSet&); - ~Phase2L1CaloToCorrelatorTMI18() override = default; + explicit Phase2L1CaloToCorrelatorTM18(const edm::ParameterSet&); + ~Phase2L1CaloToCorrelatorTM18() override = default; static void fillDescriptions(edm::ConfigurationDescriptions&); @@ -38,18 +38,18 @@ class Phase2L1CaloToCorrelatorTMI18 : public edm::stream::EDProducer<> { edm::EDGetTokenT gctHadDigiClustersSrc_; }; -Phase2L1CaloToCorrelatorTMI18::Phase2L1CaloToCorrelatorTMI18(const edm::ParameterSet& cfg) +Phase2L1CaloToCorrelatorTM18::Phase2L1CaloToCorrelatorTM18(const edm::ParameterSet& cfg) : gctEmDigiClustersSrc_( consumes(cfg.getParameter("gctEmDigiClusters"))), gctHadDigiClustersSrc_( consumes(cfg.getParameter("gctHadDigiClusters"))) { - produces("DigitizedCaloToCorrelatorTMI18"); + produces("DigitizedCaloToCorrelatorTM18"); } -void Phase2L1CaloToCorrelatorTMI18::produce(edm::Event& evt, const edm::EventSetup& es) { +void Phase2L1CaloToCorrelatorTM18::produce(edm::Event& evt, const edm::EventSetup& es) { using namespace edm; - std::unique_ptr caloCandsTMI18( - std::make_unique()); + std::unique_ptr caloCandsTM18( + std::make_unique()); int EM_SLR1_POS_OFFSET = 1; int EM_SLR1_NEG_OFFSET = 17; @@ -266,21 +266,21 @@ void Phase2L1CaloToCorrelatorTMI18::produce(edm::Event& evt, const edm::EventSet } } - l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_0 = - l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card0, clusterCollCard0); - l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_1 = - l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card1, clusterCollCard1); - l1tp2::DigitizedCaloToCorrelatorTMI18 l1CaloTMI18_2 = - l1tp2::DigitizedCaloToCorrelatorTMI18(dataToCL1Card2, clusterCollCard2); + l1tp2::DigitizedCaloToCorrelatorTM18 l1CaloTM18_0 = + l1tp2::DigitizedCaloToCorrelatorTM18(dataToCL1Card0, clusterCollCard0); + l1tp2::DigitizedCaloToCorrelatorTM18 l1CaloTM18_1 = + l1tp2::DigitizedCaloToCorrelatorTM18(dataToCL1Card1, clusterCollCard1); + l1tp2::DigitizedCaloToCorrelatorTM18 l1CaloTM18_2 = + l1tp2::DigitizedCaloToCorrelatorTM18(dataToCL1Card2, clusterCollCard2); - caloCandsTMI18->push_back(l1CaloTMI18_0); - caloCandsTMI18->push_back(l1CaloTMI18_1); - caloCandsTMI18->push_back(l1CaloTMI18_2); - evt.put(std::move(caloCandsTMI18), "DigitizedCaloToCorrelatorTMI18"); + caloCandsTM18->push_back(l1CaloTM18_0); + caloCandsTM18->push_back(l1CaloTM18_1); + caloCandsTM18->push_back(l1CaloTM18_2); + evt.put(std::move(caloCandsTM18), "DigitizedCaloToCorrelatorTM18"); } // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ -void Phase2L1CaloToCorrelatorTMI18::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { +void Phase2L1CaloToCorrelatorTM18::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("gctEmDigiClusters", edm::InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters")); @@ -289,4 +289,4 @@ void Phase2L1CaloToCorrelatorTMI18::fillDescriptions(edm::ConfigurationDescripti descriptions.addWithDefaultLabel(desc); } -DEFINE_FWK_MODULE(Phase2L1CaloToCorrelatorTMI18); +DEFINE_FWK_MODULE(Phase2L1CaloToCorrelatorTM18); diff --git a/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py b/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTM18_cfi.py similarity index 79% rename from L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py rename to L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTM18_cfi.py index 42af91b4f3956..634608d4135f0 100644 --- a/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTMI18_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/l1tPhase2CaloToCorrelatorTM18_cfi.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -l1tPhase2CaloToCorrelatorTMI18 = cms.EDProducer("Phase2L1CaloToCorrelatorTMI18", +l1tPhase2CaloToCorrelatorTM18 = cms.EDProducer("Phase2L1CaloToCorrelatorTM18", gctEmDigiClusters = cms.InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTEmDigiClusters"), gctHadDigiClusters = cms.InputTag("l1tPhase2GCTBarrelToCorrelatorLayer1Emulator", "GCTHadDigiClusters"), ) diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 11b47720b7cdd..d12838abeb67d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -50,7 +50,7 @@ //#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" //#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTMI18.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h" #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" @@ -81,7 +81,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { edm::EDGetTokenT hadHGCalCands_; // can alternately give the raw containers (for GCT) - edm::EDGetTokenT gctRawCands_; + edm::EDGetTokenT gctRawCands_; float emPtCut_, hadPtCut_; @@ -282,7 +282,7 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet const edm::InputTag gctClusters = iConfig.getParameter("gctClusters"); if (!gctClusters.label().empty()) { if (gctEmInAlgo == "Emulator" || gctHadInAlgo == "Emulator") { - gctRawCands_ = consumes(gctClusters); + gctRawCands_ = consumes(gctClusters); } if (gctEmInAlgo == "Emulator") { gctEmInput_ = std::make_unique( // FIXME diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 13d457e3e02d2..9dcae3b2de177 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -13,7 +13,7 @@ l1tLayer1Barrel = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','prompt'), - gctClusters = cms.InputTag("l1tPhase2CaloToCorrelatorTMI18", "DigitizedCaloToCorrelatorTMI18"), + gctClusters = cms.InputTag("l1tPhase2CaloToCorrelatorTM18", "DigitizedCaloToCorrelatorTM18"), # hadClusters = cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated'), -- if you use Ideal gctHadInputConversionAlg vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), nVtx = cms.int32(1), diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 4f59b330e4dbb..4a732aa71112f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -85,14 +85,14 @@ from L1Trigger.Phase2L1ParticleFlow.l1tMETPFProducer_cfi import l1tMETPFProducer process.l1tMETPFProducer = l1tMETPFProducer.clone() -from L1Trigger.L1CaloTrigger.l1tPhase2CaloToCorrelatorTMI18_cfi import l1tPhase2CaloToCorrelatorTMI18 -process.l1tPhase2CaloToCorrelatorTMI18 = l1tPhase2CaloToCorrelatorTMI18.clone() +from L1Trigger.L1CaloTrigger.l1tPhase2CaloToCorrelatorTM18_cfi import l1tPhase2CaloToCorrelatorTM18 +process.l1tPhase2CaloToCorrelatorTM18 = l1tPhase2CaloToCorrelatorTM18.clone() process.L1TInputTask = cms.Task( process.l1tPhase2L1CaloEGammaEmulator, process.l1tPhase2CaloPFClusterEmulator, process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator, - process.l1tPhase2CaloToCorrelatorTMI18, + process.l1tPhase2CaloToCorrelatorTM18, process.l1tSAMuonsGmt, process.l1tGTTInputProducer, process.l1tTrackSelectionProducer, @@ -312,4 +312,3 @@ ) process.source.fileNames = [ '/store/cmst3/group/l1tr/FastPUPPI/14_2_X/fpinputs_140X/v0/TT_PU200/inputs140X_1.root' ] -process.source.fileNames = ["file:inputs140X_1.root "] From f28cbf93d7fd737b36ec490493b33203ec87c80f Mon Sep 17 00:00:00 2001 From: pallabidas Date: Mon, 23 Mar 2026 22:48:28 +0100 Subject: [PATCH 48/92] change default value of fb --- .../L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index 93d1d04cdf906..d8108261b9ffa 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -276,7 +276,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E spare = 4; // 3rd bit encode PosEta ap_uint<12> pf_et = (ap_uint<12>)(pfIn.clusterEt() / p2eg::ECAL_LSB); ap_uint<12> pf_ecal = (ap_uint<12>)(pfIn.ecalEt() / p2eg::ECAL_LSB); - l1tp2::GCTHadDigiCluster pfOut = l1tp2::GCTHadDigiCluster(pf_et, pf_eta, pf_phi, pf_ecal, 0x3F, spare); + l1tp2::GCTHadDigiCluster pfOut = l1tp2::GCTHadDigiCluster(pf_et, pf_eta, pf_phi, pf_ecal, 0x0, spare); pfOut.setRef(edm::Ref(inputPFClusters, iCluster)); From 3dd7522a4668744cfcbab6533d13c975dee50fa8 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Thu, 26 Mar 2026 11:48:17 +0100 Subject: [PATCH 49/92] update hoe for GCT tower --- .../interface/Phase2L1CaloEGammaUtils.h | 85 +++++++++---------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 15e3b7c0cc42b..5dc08b193d601 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -686,34 +686,25 @@ namespace p2eg { void addHoverEToTower(ap_uint<12> ECAL, ap_uint<12> HCAL) { ap_uint<4> hoeOut; ap_uint<1> hoeLSB = 0; - ap_uint<4> hoe = 0; + ap_uint<3> hoe = 0; ap_uint<12> A; ap_uint<12> B; A = (ECAL > HCAL) ? ECAL : HCAL; B = (ECAL > HCAL) ? HCAL : ECAL; - if (ECAL == 0 || HCAL == 0 || HCAL >= ECAL) - hoeLSB = 0; - else - hoeLSB = 1; - if (A > B) { - if (A > 2 * B) - hoe = 0x1; - if (A > 4 * B) - hoe = 0x2; - if (A > 8 * B) - hoe = 0x3; - if (A > 16 * B) - hoe = 0x4; - if (A > 32 * B) - hoe = 0x5; - if (A > 64 * B) - hoe = 0x6; - if (A > 128 * B) - hoe = 0x7; - } - hoeOut = hoeLSB | (hoe << 1); + if (HCAL >= ECAL) hoeLSB = 0 ; + else hoeLSB = 1 ; + if (A > (B << 7)) hoe = 0b111; + else if (A > (B << 6)) hoe = 0b110; + else if (A > (B << 5)) hoe = 0b101; + else if (A > (B << 4)) hoe = 0b100; + else if (A > (B << 3)) hoe = 0b011; + else if (A > (B << 2)) hoe = 0b010; + else if (A > (B << 1)) hoe = 0b001; + else hoe = 0b000; + + hoeOut = hoeLSB | (hoe << 1) ; ap_uint<16> hoeOutLong = ((((ap_uint<16>)hoeOut) << 12) | 0x0000); // e.g. 0b ____ 0000 0000 0000 where ___ are the hoe digits // Take the logical OR to preserve the saturation and tower ET bits @@ -1373,7 +1364,7 @@ namespace p2eg { class GCTtower_t { public: ap_uint<12> et; - ap_uint<6> hoe; + ap_uint<4> hoe; ap_uint<2> fb; // not defined yet in emulator // For CMSSW outputs, not firmware ap_uint<12> ecalEt; @@ -1394,28 +1385,36 @@ namespace p2eg { */ void initFromRCTTower(const RCTtower_t& rctTower) { et = rctTower.et; - int hoe_int = 0; - //hoe_int = (int)(rctTower.hoe * 63 / 15); // RCT hoe is 4 bits - hoe = hoe_int & 0x3F; - ecalEt = rctTower.ecalEt; - hcalEt = rctTower.hcalEt; - if (ecalEt > hcalEt && ecalEt > 0) { - hoe_int = (int)(hcalEt * 63 / ecalEt); - } else { - hoe_int = 63; - } - hoe = hoe_int & 0x3F; + hoe = rctTower.hoe; + // get E and H from et and hoe + ap_uint<12> A = et >> (hoe >> 1); + ap_uint<12> B = et - A; + ecalEt = ((hoe & 0x1) == 1) ? B : A; + hcalEt = ((hoe & 0x1) == 1) ? A : B; } - void addHoverEToTower(ap_uint<12> ecalEt, ap_uint<12> hcalEt) { - int hoe_int = 0; - if (ecalEt > hcalEt && ecalEt > 0) { - hoe_int = (int)(hcalEt * 63 / ecalEt); - } else { - hoe_int = 63; - } - hoe = hoe_int & 0x3F; - } + void addHoverEToTower(ap_uint<12> ECAL, ap_uint<12> HCAL) { + ap_uint<3> hoeOut; + ap_uint<1> hoeLSB = 0 ; + ap_uint<12> A; + ap_uint<12> B; + + A = (ECAL > HCAL) ? ECAL : HCAL; + B = (ECAL > HCAL) ? HCAL : ECAL; + + if (HCAL >= ECAL) hoeLSB = 0 ; + else hoeLSB = 1 ; + if (A > (B << 7)) hoeOut = 0b111; + else if (A > (B << 6)) hoeOut = 0b110; + else if (A > (B << 5)) hoeOut = 0b101; + else if (A > (B << 4)) hoeOut = 0b100; + else if (A > (B << 3)) hoeOut = 0b011; + else if (A > (B << 2)) hoeOut = 0b010; + else if (A > (B << 1)) hoeOut = 0b001; + else hoeOut = 0b000; + + hoe = hoeLSB | (hoeOut << 1) ; + } /* * Correlator fiber convention -> Global GCT convention From c99313ad7243c7775ed15fcf7e266439be58160e Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Thu, 9 Apr 2026 14:14:23 -0500 Subject: [PATCH 50/92] fix matching with pf input/output --- .../python/l1ctLayer1_patternWriters_cff.py | 4 ++-- .../Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 16b492ddd96d5..1b2d727978b3d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -248,8 +248,8 @@ barrelWriterDebugPFOutConfigsAPx = _barrelWriterOutputOnly.clone( fileFormat = cms.string("APx"), nPFOutCharged = cms.uint32(22), - nPFOutPhoton = cms.uint32(12), - nPFOutNeutral = cms.uint32(15), + nPFOutPhoton = cms.uint32(0), # we are using merged neutrals + nPFOutNeutral = cms.uint32(27), nPFOutMuon = cms.uint32(2), nOutputFramesPerBX = cms.uint32(3), #(18 * 2/3 (going to 240) * 1/2 (doing II = 2)) debugFileName = cms.string("l1BarrelApx-pfout") diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp index b3b108a53bb58..ab82d6daec544 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp @@ -302,6 +302,15 @@ void l1ct::PFAlgo3Emulator::run(const PFInputRegion& in, OutputRegion& out) cons in.region.floatPhiCenter() + in.region.floatPhiHalfWidthExtra(), in.region.pack().to_string(16).c_str()); + dbgPrintf("FW\nFW \t region int eta %+d [ %+d , %+d ], phi %+d [ %+d , %+d ] packed %s\n", + in.region.intEtaCenter(), + (in.region.hwEtaCenter - in.region.hwEtaHalfWidth - in.region.hwEtaExtra).to_int(), + (in.region.hwEtaCenter + in.region.hwEtaHalfWidth + in.region.hwEtaExtra).to_int(), + in.region.intPhiCenter(), + (in.region.hwPhiCenter - in.region.hwPhiHalfWidth - in.region.hwPhiExtra).to_int(), + (in.region.hwPhiCenter + in.region.hwPhiHalfWidth + in.region.hwPhiExtra).to_int(), + in.region.pack().to_string(16).c_str()); + dbgPrintf("FW \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", in.track.size(), in.emcalo.size(), @@ -571,6 +580,9 @@ void l1ct::PFAlgo3Emulator::run(const PFInputRegion& in, OutputRegion& out) cons } void l1ct::PFAlgo3Emulator::mergeNeutrals(OutputRegion& out) const { + // To better match the firmware, the pfphotons are first padded to their maximum size. + // This matches the fixed port assignemtns in the firmware design. + out.pfphoton.resize(nPHOTON_); out.pfphoton.reserve(out.pfphoton.size() + out.pfneutral.size()); out.pfphoton.insert(out.pfphoton.end(), out.pfneutral.begin(), out.pfneutral.end()); out.pfphoton.swap(out.pfneutral); From a76cfcdcf37384455cb5a57f199ad392688d5089 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Sun, 12 Apr 2026 17:58:26 -0500 Subject: [PATCH 51/92] add egamma debug output --- .../L1TCorrelatorLayer1PatternFileWriter.h | 2 + .../python/l1ctLayer1_patternWriters_cff.py | 8 +++ .../L1TCorrelatorLayer1PatternFileWriter.cc | 49 +++++++++++++++++++ .../test/make_l1ct_binaryFiles_cfg.py | 6 ++- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h index 0302cd3e5b067..3ebc9b8634323 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -57,6 +57,8 @@ class L1TCorrelatorLayer1PatternFileWriter { const uint32_t nPFOutPhoton_; const uint32_t nPFOutNeutral_; const uint32_t nPFOutMuon_; + const uint32_t nEGElectron_; + const uint32_t nEGPhoton_; // Common stuff related to the format uint32_t nInputFramesPerBX_, nOutputFramesPerBX_; diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 1b2d727978b3d..bcada2d94e86f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -255,6 +255,14 @@ debugFileName = cms.string("l1BarrelApx-pfout") ) +barrelWriterDebugEGConfigsAPx = _barrelWriterOutputOnly.clone( + fileFormat = cms.string("APx"), + nEGElectron = cms.uint32(10), + nEGPhoton = cms.uint32(10), + nOutputFramesPerBX = cms.uint32(3), #(18 * 2/3 (going to 240) * 1/2 (doing II = 2)) + debugFileName = cms.string("l1BarrelApx-egamma") +) + # For the tracker, the logical (firmware) fiber order sorts negative eta first, then positive, # and in a given eta from most negative to most positive phi. That is reflected in this remapping trackFiberOrder = (4, 5, 6, 7, 8, 0, 1, 2, 3, 13, 14, 15, 16, 17, 9, 10, 11, 12) # phys to logical diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 0be5a89dede86..71e1a115632ce 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -28,6 +28,8 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const nPFOutPhoton_(iConfig.getParameter("nPFOutPhoton")), nPFOutNeutral_(iConfig.getParameter("nPFOutNeutral")), nPFOutMuon_(iConfig.getParameter("nPFOutMuon")), + nEGElectron_(iConfig.getParameter("nEGElectron")), + nEGPhoton_(iConfig.getParameter("nEGPhoton")), fileFormat_(iConfig.getParameter("fileFormat")), eventsPerFile_(iConfig.getParameter("eventsPerFile")), eventIndex_(0) { @@ -145,6 +147,12 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const for (unsigned int i = 0; i < nPFOutMuon_ * 2; ++i) { channelIdsOutput_[l1t::demo::LinkId{"pfout_muon", i}].push_back(linkCount++); } + for (unsigned int i = 0; i < nEGElectron_ * 2; ++i) { + channelIdsOutput_[l1t::demo::LinkId{"egout_electron", i}].push_back(linkCount++); + } + for (unsigned int i = 0; i < nEGPhoton_ * 2; ++i) { + channelIdsOutput_[l1t::demo::LinkId{"egout_photon", i}].push_back(linkCount++); + } channelSpecsOutput_["pfin_track"] = {tmuxFactor_, 0}; channelSpecsOutput_["pfin_emcalo"] = {tmuxFactor_, 0}; channelSpecsOutput_["pfin_hadcalo"] = {tmuxFactor_, 0}; @@ -153,6 +161,8 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const channelSpecsOutput_["pfout_photon"] = {tmuxFactor_, 0}; channelSpecsOutput_["pfout_neutral"] = {tmuxFactor_, 0}; channelSpecsOutput_["pfout_muon"] = {tmuxFactor_, 0}; + channelSpecsOutput_["egout_electron"] = {tmuxFactor_, 0}; + channelSpecsOutput_["egout_photon"] = {tmuxFactor_, 0}; debugFileWriter_ = std::make_unique(l1t::demo::parseFileFormat(fileFormat_), @@ -193,6 +203,8 @@ edm::ParameterSetDescription L1TCorrelatorLayer1PatternFileWriter::getParameterS description.add("nPFOutPhoton", 0); description.add("nPFOutNeutral", 0); description.add("nPFOutMuon", 0); + description.add("nEGElectron", 0); + description.add("nEGPhoton", 0); description.ifValue(edm::ParameterDescription("partition", "Barrel", true), "Barrel" >> (describeTF() and describeGCT() and describeGTT() and describeGMT() and @@ -608,6 +620,43 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, out.add(l1t::demo::LinkId{"pfout_muon", 2 * i + 1}, linksLow[i]); } } + + if (nEGElectron_) { + std::vector>> linksLow(nEGElectron_); // virtual links -- bits 63:0 + std::vector>> linksHigh(nEGElectron_); // virtual links -- bits MAX_BITWIDTH-1:64 + for (auto ir : outputRegions_) { + auto egvals = event.out[ir].egelectron; + unsigned int negvals = egvals.size(); + for (unsigned int i = 0; i < nEGElectron_; ++i) { + ap_uint val = i < negvals ? egvals[i].pack() : ap_uint(0); + linksHigh[i].push_back(val(MAX_BITWIDTH - 1, 64)); + linksLow[i].push_back(val(63, 0)); + } + } + for (unsigned int i = 0; i < linksLow.size(); ++i) { + out.add(l1t::demo::LinkId{"egout_electron", 2 * i}, linksHigh[i]); + out.add(l1t::demo::LinkId{"egout_electron", 2 * i + 1}, linksLow[i]); + } + } + + if (nEGPhoton_) { + std::vector>> linksLow(nEGPhoton_); // virtual links -- bits 63:0 + std::vector>> linksHigh(nEGPhoton_); // virtual links -- bits MAX_BITWIDTH-1:64 + for (auto ir : outputRegions_) { + auto egvals = event.out[ir].egphoton; + unsigned int negvals = egvals.size(); + for (unsigned int i = 0; i < nEGPhoton_; ++i) { + ap_uint val = i < negvals ? egvals[i].pack() : ap_uint(0); + linksHigh[i].push_back(val(MAX_BITWIDTH - 1, 64)); + linksLow[i].push_back(val(63, 0)); + } + } + for (unsigned int i = 0; i < linksLow.size(); ++i) { + out.add(l1t::demo::LinkId{"egout_photon", 2 * i}, linksHigh[i]); + out.add(l1t::demo::LinkId{"egout_photon", 2 * i + 1}, linksLow[i]); + } + } + } void L1TCorrelatorLayer1PatternFileWriter::writePuppi(const l1ct::Event& event, l1t::demo::EventData& out) { diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 4a732aa71112f..e1a53d6855249 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -145,7 +145,8 @@ nEmCalo = cms.uint32(12), nMu = cms.uint32(2), debug = cms.untracked.bool(False), - debug_emcalo = cms.untracked.bool(False) + debug_emcalo = cms.untracked.bool(False), + debug_tk = cms.untracked.bool(False) ) process.l1tLayer1BarrelTDR.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelTDR.pfAlgoParameters.nSelCalo = 15 @@ -208,7 +209,8 @@ process.l1tLayer1BarrelTDR.patternWriters = cms.untracked.VPSet(barrelInputWriterConfigsAPx, barrelOutputWriterConfigsAPx, barrelWriterDebugPFInConfigsAPx, - barrelWriterDebugPFOutConfigsAPx + barrelWriterDebugPFOutConfigsAPx, + barrelWriterDebugEGConfigsAPx ) process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) process.l1tLayer1BarrelSerenityElliptic.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) From 2be6f659bb4560f83edb7b5ebb701537ae5b256f Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 13 Apr 2026 19:00:19 -0500 Subject: [PATCH 52/92] try to make egamma match --- .../Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index e1a53d6855249..8608e0ad0675b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -158,6 +158,8 @@ process.l1tLayer1BarrelTDR.puAlgoParameters.finalSortAlgo = "BitonicVHDL" process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nTRACK_EGIN = 22 process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nEMCALO_EGIN = 12 +process.l1tLayer1BarrelTDR.tkEgAlgoParameters.algorithm = 0 +process.l1tLayer1BarrelTDR.tkEgAlgoParameters.trkQualityPtMin = 10.0 process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() process.l1tLayer1BarrelSerenity.regionizerAlgo = "MiddleBufferMultififo" From a215786b6d0d5c7312ea31a1b624bdd523474f0d Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 15 Apr 2026 21:56:09 -0500 Subject: [PATCH 53/92] fix the pattern file writer --- .../src/L1TCorrelatorLayer1PatternFileWriter.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 71e1a115632ce..f38991ea959bd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -473,11 +473,7 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, // Note: the writers have a width of 64 very much hardcoded in the sizes. Therefore, send the bits as // two separate "fibers" - constexpr unsigned int MAX_BITWIDTH = - std::max({l1ct::TkObjEmu::BITWIDTH_BARREL, - l1ct::EmCaloObjEmu::BITWIDTH_BARREL, - l1ct::HadCaloObjEmu::BITWIDTH_BARREL, - l1ct::MuObjEmu::BITWIDTH}); // Should be the biggest object width (or greater) + constexpr unsigned int MAX_BITWIDTH = 128; if (nPFInTrack_) { std::vector>> linksLow(nPFInTrack_); // virtual links -- bits 63:0 From 70ca310b7c1bb5bcd60f36e13a5069dfdcd3b48f Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 20 Apr 2026 15:56:04 -0500 Subject: [PATCH 54/92] fix egamma sort configuration --- .../interface/egamma/pftkegsorter_barrel_ref.h | 8 ++++++-- .../Phase2L1ParticleFlow/python/l1ctLayer1_cff.py | 15 ++++++++------- .../python/l1ctLayer1_patternWriters_cff.py | 7 +++++-- .../test/make_l1ct_binaryFiles_cfg.py | 1 + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h index 624b3851fa36d..16446627a8331 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h @@ -17,10 +17,14 @@ namespace l1ct { #ifdef CMSSW_GIT_HASH PFTkEGSorterBarrelEmulator(const edm::ParameterSet& iConfig) : PFTkEGSorterEmulator(iConfig.getParameter("nObjToSort"), - iConfig.getParameter("nObjSorted")) {} + iConfig.getParameter("nObjSorted")) { + debug_ = iConfig.getUntrackedParameter("debug"); + } static edm::ParameterSetDescription getParameterSetDescription() { - return PFTkEGSorterEmulator::getParameterSetDescription(); + auto description = PFTkEGSorterEmulator::getParameterSetDescription(); + description.addUntracked("debug", false); + return description; } #endif diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 9dcae3b2de177..25e1a30dd06e1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -10,6 +10,10 @@ from L1Trigger.Phase2L1ParticleFlow.mlAssociation_cfi import NNVtxAssociationPSet switchOnNNAssoc = cms.bool(False) +virtBoard0 = (5, 14, 23, 32, 41, 50, 6, 15, 24, 33, 42, 51, 7, 16, 25, 34, 43, 52) +virtBoard1 = (8, 17, 26, 35, 44, 53, 0, 9, 18, 27, 36, 45, 1, 10, 19, 28, 37, 46) +virtBoard2 = (2, 11, 20, 29, 38, 47, 3, 12, 21, 30, 39, 48, 4, 13, 22, 31, 40, 49) + l1tLayer1Barrel = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','prompt'), @@ -107,7 +111,7 @@ ), tkEgSorterAlgo = cms.string("Barrel"), tkEgSorterParameters = tkEgSorterParameters.clone( - nObjToSort = 10 + nObjToSort = 16 ), # these are the sectors for the logical "decoded" clusters; caloSectors = cms.VPSet( @@ -133,12 +137,9 @@ ), ), boards = cms.VPSet( # In TM18, this is "virtual" boards for egamma - cms.PSet( - regions = cms.vuint32(*[0+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting - cms.PSet( - regions = cms.vuint32(*[3+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting - cms.PSet( - regions = cms.vuint32(*[6+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting + cms.PSet(regions = cms.vuint32(*virtBoard0)), # phi splitting + cms.PSet(regions = cms.vuint32(*virtBoard1)), # phi splitting + cms.PSet(regions = cms.vuint32(*virtBoard2)), # phi splitting ), ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index bcada2d94e86f..61587c10ca8d6 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -7,8 +7,11 @@ ##################################################################################################################### ## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now -srOrder = (5, 14, 23, 32, 41, 50, 6, 15, 24, 33, 42, 51, 7, 16, 25, 34, 43, 52, 8, 17, 26, 35, 44, 53, 0, 9, 18, - 27, 36, 45, 1, 10, 19, 28, 37, 46, 2, 11, 20, 29, 38, 47, 3, 12, 21, 30, 39, 48, 4, 13, 22, 31, 40, 49) +virtBoard0 = (5, 14, 23, 32, 41, 50, 6, 15, 24, 33, 42, 51, 7, 16, 25, 34, 43, 52) +virtBoard1 = (8, 17, 26, 35, 44, 53, 0, 9, 18, 27, 36, 45, 1, 10, 19, 28, 37, 46) +virtBoard2 = (2, 11, 20, 29, 38, 47, 3, 12, 21, 30, 39, 48, 4, 13, 22, 31, 40, 49) + +srOrder = virtBoard0 + virtBoard1 + virtBoard2 _barrelWriterOutputOnly = cms.PSet( partition = cms.string("Barrel"), diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 8608e0ad0675b..8f95074fde037 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -156,6 +156,7 @@ process.l1tLayer1BarrelTDR.puAlgoParameters.nIn = 27 process.l1tLayer1BarrelTDR.puAlgoParameters.nOut = 27 process.l1tLayer1BarrelTDR.puAlgoParameters.finalSortAlgo = "BitonicVHDL" +process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nTRACK = 22 process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nTRACK_EGIN = 22 process.l1tLayer1BarrelTDR.tkEgAlgoParameters.nEMCALO_EGIN = 12 process.l1tLayer1BarrelTDR.tkEgAlgoParameters.algorithm = 0 From 9fe43fdad6b4faf2ad7c862f875c2b1dee41eae7 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Fri, 1 May 2026 00:06:46 +0200 Subject: [PATCH 55/92] PF cluster corrections --- .../data/hadcorr_barrel.root | Bin 0 -> 38082 bytes .../interface/l1-converters/gcthadinput_ref.h | 17 ++++++++++++++++- .../python/l1ctLayer1_cff.py | 9 +++++++++ .../src/l1-converters/gcthadinput_ref.cpp | 17 ++++++++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root new file mode 100644 index 0000000000000000000000000000000000000000..c312280f538f1e3a2a3756b652189e5a22fc99d6 GIT binary patch literal 38082 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 etas, + std::vector offsets, + std::vector scales, + std::vector ptMins, + std::vector ptMaxs) + : corrector_(corrFile), resol_(kind, etas, offsets, scales, ptMins, ptMaxs) {} ~GctHadClusterDecoderEmulator() = default; static edm::ParameterSetDescription getParameterSetDescription(); l1ct::HadCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; + private: + // tools for GCT clusters + l1tpf::corrector corrector_; + l1tpf::ParametricResolution resol_; }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 25e1a30dd06e1..d7fbaba70d3d6 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -53,6 +53,15 @@ ), ), gctHadInputConversionAlgo = cms.string("Emulator"), + gctHadInputConversionParameters = cms.PSet( + gctHadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), + gctHadResol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.654, 2.419, 1.519), + scale = cms.vdouble( 0.214, 0.252, 0.364), + kind = cms.string('calo'), + ), + ), regionizerAlgo = cms.string("Ideal"), pfAlgo = cms.string("PFAlgo3"), pfAlgoParameters = cms.PSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index 043e2808d8506..819b52bf64c6e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -5,10 +5,19 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" -l1ct::GctHadClusterDecoderEmulator::GctHadClusterDecoderEmulator(const edm::ParameterSet &pset) {} +l1ct::GctHadClusterDecoderEmulator::GctHadClusterDecoderEmulator(const edm::ParameterSet &iConfig) + : corrector_(iConfig.getParameter("gctHadCorrector"), -1), + resol_(iConfig.getParameter("gctHadResol")) {} edm::ParameterSetDescription l1ct::GctHadClusterDecoderEmulator::getParameterSetDescription() { edm::ParameterSetDescription description; + description.add("gctHadCorrector"); + edm::ParameterSetDescription gctHadResolPSD; + gctHadResolPSD.add>("etaBins"); + gctHadResolPSD.add>("offset"); + gctHadResolPSD.add>("scale"); + gctHadResolPSD.add("kind"); + description.add("gctHadResol", gctHadResolPSD); return description; } #endif @@ -27,6 +36,12 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwEta = l1ct::Scales::makeGlbEta(inclus.eta() * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame + if (corrector_.valid()) { + float newpt = + corrector_.correctedPt(calo.floatPt(), calo.floatPt(), calo.floatEta()); // NOTE: this is still abs(globalEta) + calo.hwPt = l1ct::Scales::makePtFromFloat(newpt); + } + // need to add EmPt when it becomes available calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); From 9fa6fc33669034237f3e13483afd41e9c7ca3ad3 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Sat, 2 May 2026 19:18:09 +0200 Subject: [PATCH 56/92] corrections after EM corrections are applied --- .../data/hadcorr_barrel.root | Bin 38082 -> 38065 bytes .../python/l1ctLayer1_cff.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root index c312280f538f1e3a2a3756b652189e5a22fc99d6..141cb1897bbeee786dcb0e5591d2a0f9845bc43b 100644 GIT binary patch delta 29832 zcmcG#byQSw_x}r0(jZ882ugRi2#9n^Nr!Yd90}}bI?Q?T-ury7cu-gIK*qz>)e8j$3PC|Zu|`2jt3w{f z$nW)$2P*RLLq~qGK|ul7QBVl7QBc!Q2PI$N5}zcJJ#hTm(RG|6_k;ljr4i+Cntkx| zb_tYM|Mnqkp`c*szIf|o^9%$}V8AouQ?u~r{&%&10nz_k00rakPUP_#1qJg1a-$#e z_*Vf1C87KOanTe674GwPS(GP#uY*d_z=BGPN;32J2YC1tS>id$%fAZ`ltG~&2GA%T zE(mylhZ+vbQ+);^!pB0#v<{sEsq0$;2(6;7oo^+1&;stzZ#FOuR0vEmcKJ}Iqn&Yw z13G_K`~pv62+jeeXFfHFtv#+oB%3?bZAYcRVO*25U+xO55#7*`xSmUK7-2#J_;}2< z5kd6xPM%AB;SR0+mS*-53GA`}(1qdH&x17trdO$H%@N%P6Ci{S&!Nn&0Sl!BKl}?~ zZ8ZN$(=J7F!Mb};KL?C(KWtsEM)r(pm5cqEGaBfIDUC>^Jp!FR@3kYM5-c#3>`x1- zb9xG@QR4s}i{rTbG}wobo57ey19XN$Mqd;L%jDBF7O>4-yJYXl!!W`E6@`~@nhGSe z;1lT^LC{H1C)m1^?@PfB4V-BsG&&gZd1#0-VP)ZxzRjXN^CAkqsb{cq6a>t48SLwx z76pz$B*0%Eo8=f<$yD@z*-j7v1s|lgVpY){%mcnJ;oDj8x0S&g%L~Gj=Oa*%_E=R* zU69MF1AG;7hc5(+95l!+&0XPNaOD*L`Au4GCy2#)$>pIVn`D=-X5UKJf{TP>+6)%V za?;GF-8l{t7x*Jn+PKEv>@*;Dv)@S%_5c=aBynwn6000NgS-h7{@zd6Yya*ivA_2d zCLM?Y^9i7eiL!=`;)g0UhNUInImUr~6K4O>Vgyx1m zKFsXTiEVmGO9~&nB_)xSboe6veX_Avm%J#cMQ%z7eW9Chr?*U!4fF>A zzY&!HXHm>z_`9%g-_vH5i2bfsKXes!649I5H4oCu{W`&Dx>F^++WisUDXxIF-Ewqv z`x1uU?ffASYqRd57{neC=fy#mE4Bycz99~1e)!wM;-Q3yMghm0q$G)}_3EzKKZDm? zi|Qli3VsIPLn;HGGPNmj`>F5CTOZ$bM_^CZ0e>v>H>ei%WZztDuM{qR1I{`!$&&hu zZ1_fcz!(S$q7G15;b_#DQt1k z|By_)9TLpLt9$Pv&1E31bO>U@TGtW#k=Rq6))Bu>UzYIcG(P|y9TSiOWx#{l9 z0_>G#2;o+*5A2e=yu1&wYZY$kG50+QXq9e{Azcb*i13KiNCoc^l9WGfy8N>|=rN@W zs?~^L`E|EnmXInL<~`j0ezbNjWvV@d&ifrbmdqxxcEB;5G>29qXSEudAwF66=&5I3Sc_Q)S?p1)ow>MBeJ!O{GS^U_X?fZAqhv zVA^(-QivK;(ApE%yUC4Of0b?F`A3Hxg4NY-|Rb3Tum9uD=HTbI)8Ey&gx|AjLRM1Fj{ z97L~6+fESRw;Uc2w&A9}O*9qLTQ_pSt!Z%K8WikJHnpP{Jn_`xmuR#9RE5q*6$0Mn zDgn8(i^M0ZD@^unG<4M=EjUJHLWR|X5`}85I>LnxGL6%*4IexqzkCq8Q-4OiOT>V3 zy67e*wJvyV;bR}=%3zqfe-8Bo5HNDqMk!O$zQpa76ffV#zoiT{!k-YKZK$IeRJc(z z+p8ouW9adAOkgP?pnSH-ku$u?Xm$3omYS!?^_)>hzJbav~De2 z;DRi&o_rANpC^wTuJy##VKSdPY2W(sf)!6Bqr+`?0QJBNFwjv%pL<6+?%|64IvaY_ zAdE5hc-5&~#5Sy2dIKB{3}Ut)>m4tfVweYp>AS{rqB@RvldP7%8~2~B<8Z9B!0Q;! z2ylwh;v09_PI*CL@B+~(1rMZfj3dbei$1h!u=(Y^s6r746QL#8i#Vw>P@X9r;#Jc& zZ4fx)#n4L^Ze58|nHN@=IVJt1$D=NzgV&=={^fj8iGUZLyb=8YP~kOQsylZ1CYY6P z@~V3OLxKjIgd{l+`QkU1!?<4aN7vGO>H#SN%B~({VmarmJ1HU7D3q^-n`K{NrqHLH z4Vv>un8-$^T5R@jvRR8#%DqTESHb+&LHSY7jaYe~9VvUHD3E%Ml<2;w19nq{(Mzt< z#InRP^^bu1NA(h}V>@Anvp0EUF$XJmsV*oP#MH=AWaj zRT4Kb^q5jv#Zt+2RPO?ZzV>{99=MKhdZ6xt;g9 zK*N35p6FkFhJ#m_sUG$3su;Pf3Ew^z6bFTtZJ2yo_<|)eC3 ztPn;~$L~I$(ZLMPX4IDFZkF$w_I4T=Yo9EF$^3-gLgfu$fPoTa;#jJ&Gh$&kKQb^e z5q=;Gsg`d?gP3u^R}e-No3z&mS)z52p~(XrUpY+u*PMK^@6gcBRK7eSR1o=yvn_@9 zP1GXQat-D4i&&i}m`odKp`pa(B#+8?LOG{I)zD%$`Q1=eEZlAdWKkRyEfsC~211|V zamte1g|aqPf%>@U0IyL>22tFN;z@!zt|}I%-w!Y`S#T*K1%m?`^GrU2cbT(eV`c

9M5HX}&(K_5)frKs?X`2@iuHC%CK3 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 delta 30145 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 R~khc?(ciw$Y7;wO=S;T=$wx9p;R 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 W^&htf{$IBT;+}ff>B;{N>Hh%~Pa(Dd diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index d7fbaba70d3d6..059b437b975ec 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -57,8 +57,8 @@ gctHadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), gctHadResol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 2.654, 2.419, 1.519), - scale = cms.vdouble( 0.214, 0.252, 0.364), + offset = cms.vdouble( 3.757, 3.197, 1.744), + scale = cms.vdouble( 0.175, 0.222, 0.354), kind = cms.string('calo'), ), ), From 1e6b558d8c66048b0959ff7068fb84957be9de29 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 4 May 2026 10:53:53 -0500 Subject: [PATCH 57/92] scram code format changes --- .../interface/Phase2L1CaloEGammaUtils.h | 74 ++++++++++++------- .../interface/l1-converters/gcthadinput_ref.h | 13 ++-- .../tdr_regionizer_elements_ref.icc | 21 +++--- .../L1TCorrelatorLayer1PatternFileWriter.cc | 1 - .../src/l1-converters/gcteminput_ref.cpp | 4 +- 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 5dc08b193d601..53abf57508bf2 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -693,18 +693,28 @@ namespace p2eg { A = (ECAL > HCAL) ? ECAL : HCAL; B = (ECAL > HCAL) ? HCAL : ECAL; - if (HCAL >= ECAL) hoeLSB = 0 ; - else hoeLSB = 1 ; - if (A > (B << 7)) hoe = 0b111; - else if (A > (B << 6)) hoe = 0b110; - else if (A > (B << 5)) hoe = 0b101; - else if (A > (B << 4)) hoe = 0b100; - else if (A > (B << 3)) hoe = 0b011; - else if (A > (B << 2)) hoe = 0b010; - else if (A > (B << 1)) hoe = 0b001; - else hoe = 0b000; - - hoeOut = hoeLSB | (hoe << 1) ; + if (HCAL >= ECAL) + hoeLSB = 0; + else + hoeLSB = 1; + if (A > (B << 7)) + hoe = 0b111; + else if (A > (B << 6)) + hoe = 0b110; + else if (A > (B << 5)) + hoe = 0b101; + else if (A > (B << 4)) + hoe = 0b100; + else if (A > (B << 3)) + hoe = 0b011; + else if (A > (B << 2)) + hoe = 0b010; + else if (A > (B << 1)) + hoe = 0b001; + else + hoe = 0b000; + + hoeOut = hoeLSB | (hoe << 1); ap_uint<16> hoeOutLong = ((((ap_uint<16>)hoeOut) << 12) | 0x0000); // e.g. 0b ____ 0000 0000 0000 where ___ are the hoe digits // Take the logical OR to preserve the saturation and tower ET bits @@ -1312,7 +1322,7 @@ namespace p2eg { } // normalize hoe to 0x3F - int hoe_int = (int)(hoe * 63 /15); + int hoe_int = (int)(hoe * 63 / 15); return l1tp2::DigitizedClusterCorrelator( et, // technically we are just multiplying and then dividing again by the LSB @@ -1395,26 +1405,36 @@ namespace p2eg { void addHoverEToTower(ap_uint<12> ECAL, ap_uint<12> HCAL) { ap_uint<3> hoeOut; - ap_uint<1> hoeLSB = 0 ; + ap_uint<1> hoeLSB = 0; ap_uint<12> A; ap_uint<12> B; A = (ECAL > HCAL) ? ECAL : HCAL; B = (ECAL > HCAL) ? HCAL : ECAL; - if (HCAL >= ECAL) hoeLSB = 0 ; - else hoeLSB = 1 ; - if (A > (B << 7)) hoeOut = 0b111; - else if (A > (B << 6)) hoeOut = 0b110; - else if (A > (B << 5)) hoeOut = 0b101; - else if (A > (B << 4)) hoeOut = 0b100; - else if (A > (B << 3)) hoeOut = 0b011; - else if (A > (B << 2)) hoeOut = 0b010; - else if (A > (B << 1)) hoeOut = 0b001; - else hoeOut = 0b000; - - hoe = hoeLSB | (hoeOut << 1) ; - } + if (HCAL >= ECAL) + hoeLSB = 0; + else + hoeLSB = 1; + if (A > (B << 7)) + hoeOut = 0b111; + else if (A > (B << 6)) + hoeOut = 0b110; + else if (A > (B << 5)) + hoeOut = 0b101; + else if (A > (B << 4)) + hoeOut = 0b100; + else if (A > (B << 3)) + hoeOut = 0b011; + else if (A > (B << 2)) + hoeOut = 0b010; + else if (A > (B << 1)) + hoeOut = 0b001; + else + hoeOut = 0b000; + + hoe = hoeLSB | (hoeOut << 1); + } /* * Correlator fiber convention -> Global GCT convention diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h index e05bf3cc4e92e..dacc453664a41 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/gcthadinput_ref.h @@ -19,12 +19,12 @@ namespace l1ct { GctHadClusterDecoderEmulator() {}; GctHadClusterDecoderEmulator(const edm::ParameterSet &iConfig); GctHadClusterDecoderEmulator(const std::string &corrFile, - l1tpf::ParametricResolution::Kind kind, - std::vector etas, - std::vector offsets, - std::vector scales, - std::vector ptMins, - std::vector ptMaxs) + l1tpf::ParametricResolution::Kind kind, + std::vector etas, + std::vector offsets, + std::vector scales, + std::vector ptMins, + std::vector ptMaxs) : corrector_(corrFile), resol_(kind, etas, offsets, scales, ptMins, ptMaxs) {} ~GctHadClusterDecoderEmulator() = default; @@ -32,6 +32,7 @@ namespace l1ct { static edm::ParameterSetDescription getParameterSetDescription(); l1ct::HadCaloObjEmu decode(const l1ct::PFRegionEmu §or, const ap_uint<64> &in) const; + private: // tools for GCT clusters l1tpf::corrector corrector_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index ab6a292f41ef0..868d1243bcf95 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -351,13 +351,15 @@ inline std::vector> l1ct::tdr_regionizer::Regionizer::cal } template <> -inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR( + size_t sr) const { const std::pair logic_sr = get_small_region(sr); return caloLinksHelper(logic_sr.second); } template <> -inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR(size_t sr) const { +inline std::vector> l1ct::tdr_regionizer::Regionizer::linksForSR( + size_t sr) const { const std::pair logic_sr = get_small_region(sr); return caloLinksHelper(logic_sr.second); } @@ -387,8 +389,10 @@ std::pair l1ct::tdr_regionizer::Regionizer::get_small_region( // Note that this also updates the index so that if if's not empty, you can directly access value // One needs to check that the next index is not bundle.size() template -void l1ct::tdr_regionizer::Regionizer::getNextIndex(size_t sr, const std::vector& bundle, size_t& nextIdx) const { - for (;nextIdx < bundle.size(); nextIdx++) { +void l1ct::tdr_regionizer::Regionizer::getNextIndex(size_t sr, + const std::vector& bundle, + size_t& nextIdx) const { + for (; nextIdx < bundle.size(); nextIdx++) { auto& buffer = buffers_[bundle[nextIdx]]; if (!buffer.empty(sr)) { return; @@ -396,7 +400,6 @@ void l1ct::tdr_regionizer::Regionizer::getNextIndex(size_t sr, const std::vec } } - template void l1ct::tdr_regionizer::Regionizer::run() { if (debug_) @@ -404,8 +407,8 @@ void l1ct::tdr_regionizer::Regionizer::run() { for (size_t sr = 0; sr < regionmap_.size(); sr++) { // iterate over the (logical) SRs - auto links = linksForSR(sr); // these are the physical links, in bundles - std::vector nextIndex(links.size(), 0); // this is per bundle + auto links = linksForSR(sr); // these are the physical links, in bundles + std::vector nextIndex(links.size(), 0); // this is per bundle auto physSR = regionmap_[sr]; bool allEmpty; do { @@ -463,8 +466,8 @@ void l1ct::tdr_regionizer::Regionizer::printDebug(int count) const { for (unsigned int j = 0; j < smallRegionObjects_[physRegIdx].size(); j++) { dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t\t" << physRegIdx << "\t" << j << "\t" << smallRegionObjects_[physRegIdx][j].intPt() << "\t" << smallRegionObjects_[physRegIdx][j].intEta() - << "\t" << smallRegionObjects_[physRegIdx][j].intPhi() - << "\t" << smallRegionObjects_[physRegIdx][j].pack().to_string(16) << std::endl; + << "\t" << smallRegionObjects_[physRegIdx][j].intPhi() << "\t" + << smallRegionObjects_[physRegIdx][j].pack().to_string(16) << std::endl; } dbgCout() << "-------------------------------" << std::endl; } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index f38991ea959bd..7146c6261ce85 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -652,7 +652,6 @@ void L1TCorrelatorLayer1PatternFileWriter::writeDebugs(const l1ct::Event& event, out.add(l1t::demo::LinkId{"egout_photon", 2 * i + 1}, linksLow[i]); } } - } void L1TCorrelatorLayer1PatternFileWriter::writePuppi(const l1ct::Event& event, l1t::demo::EventData& out) { diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp index a1d862132ce8c..1ef85d6618f8e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcteminput_ref.cpp @@ -57,8 +57,8 @@ l1ct::EmCaloObjEmu l1ct::GctEmClusterDecoderEmulator::decode(const l1ct::PFRegio calo.hwEmID = inclus.wp(); // Copying the bits directly. - calo.hwRelIso(rel_iso_t::width-1, 0) = inclus.iso()(rel_iso_t::width-1, 0); - calo.hwShowerShape(shower_shape_t::width-1, 0) = inclus.shape()(shower_shape_t::width-1, 0); + calo.hwRelIso(rel_iso_t::width - 1, 0) = inclus.iso()(rel_iso_t::width - 1, 0); + calo.hwShowerShape(shower_shape_t::width - 1, 0) = inclus.shape()(shower_shape_t::width - 1, 0); // convert eta to local if (sector.hwEtaCenter < 0) { From 75fb58260a2aa80dc0798a71c4b58a4e088b51f4 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 4 May 2026 22:25:22 -0500 Subject: [PATCH 58/92] fix copilot suggestions --- .../interface/DigitizedCaloToCorrelatorTM18.h | 1 + .../L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h | 1 + .../L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h | 1 - .../interface/regionizer/tdr_regionizer_elements_ref.icc | 4 ++++ .../plugins/L1TCorrelatorLayer1Producer.cc | 2 +- L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp | 2 +- 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h index fbded5ce8c5ad..ab6b6aa484c74 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h @@ -2,6 +2,7 @@ #define DataFormats_L1TCalorimeterPhase2_DigitizedCaloToCorrelatorTM18_h #include +#include #include #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h index 269dcc4001058..33779365e7589 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedL1CaloJet.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "DataFormats/L1Trigger/interface/L1Candidate.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h index 86b55016bb4f1..84575d283d967 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h @@ -41,6 +41,5 @@ // // class declaration // -using std::vector; #endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index 868d1243bcf95..ed5bcef5ee56f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -278,6 +278,10 @@ void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(size_t sr, BufferEntr << ", loc eta = " << rawObj.intEta() << ", loc phi = " << rawObj.intPhi() << std::endl; } + if (smallRegionObjects_[sr].size() >= maxobjects_) { + return; + } + smallRegionObjects_[sr].push_back(rawObj); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index d12838abeb67d..1d1bbcdec6ffe 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -1039,7 +1039,7 @@ void L1TCorrelatorLayer1Producer::addGCTCaloRaw(const l1tp2::GCTDigiClusterLink unsigned int linkidx, unsigned int entidx) { if (auto p = std::get_if(&link[entidx])) { - // (For EM don't currently suport ideal, so it is always Emulated) + // (For EM don't currently support ideal, so it is always Emulated) event_.raw.gctcluster[linkidx].obj.push_back(p->data()); if (p->pt() > 0) { auto decidx = emDecodedIndex(linkidx, entidx); diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp index ab82d6daec544..89bcef1481f4f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp @@ -581,7 +581,7 @@ void l1ct::PFAlgo3Emulator::run(const PFInputRegion& in, OutputRegion& out) cons void l1ct::PFAlgo3Emulator::mergeNeutrals(OutputRegion& out) const { // To better match the firmware, the pfphotons are first padded to their maximum size. - // This matches the fixed port assignemtns in the firmware design. + // This matches the fixed port assignments in the firmware design. out.pfphoton.resize(nPHOTON_); out.pfphoton.reserve(out.pfphoton.size() + out.pfneutral.size()); out.pfphoton.insert(out.pfphoton.end(), out.pfneutral.begin(), out.pfneutral.end()); From ff65c302c85af8eabd9468698c932029c54980be Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 5 May 2026 18:05:01 +0200 Subject: [PATCH 59/92] initial attempt towards a working config --- .../test/make_l1ct_binaryFiles_cfg.py | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 8f95074fde037..a842cae4391c3 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -1,5 +1,6 @@ import argparse import sys +import math # example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py --patternFilesOFF # example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py --dumpFilesOFF --serenity @@ -41,21 +42,15 @@ "drop l1tPFClusters_*_*_*", "drop l1tPFTracks_*_*_*", "drop l1tPFCandidates_*_*_*", - "drop l1tTkPrimaryVertexs_*_*_*") + "drop l1tTkPrimaryVertexs_*_*_*"), + skipEvents = cms.untracked.uint32(0), ) process.load('Configuration.Geometry.GeometryExtendedRun4D110Reco_cff') process.load('Configuration.Geometry.GeometryExtendedRun4D110_cff') process.load('Configuration.StandardSequences.MagneticField_cff') -process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs -process.load('SimCalorimetry.HGCalSimProducers.hgcalDigitizer_cfi') # needed for HGCAL_noise_fC process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') -process.load('RecoMET.Configuration.GenMETParticles_cff') -process.load('RecoMET.METProducers.genMetTrue_cfi') - -from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets -from RecoMET.METProducers.pfMet_cfi import pfMet from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, '141X_mcRun4_realistic_v3', '') @@ -79,12 +74,6 @@ from L1Trigger.L1CaloTrigger.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi import l1tPhase2GCTBarrelToCorrelatorLayer1Emulator process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = l1tPhase2GCTBarrelToCorrelatorLayer1Emulator.clone() -from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cff import l1tNNTauProducerPuppi -process.l1tNNTauProducerPuppi = l1tNNTauProducerPuppi.clone() - -from L1Trigger.Phase2L1ParticleFlow.l1tMETPFProducer_cfi import l1tMETPFProducer -process.l1tMETPFProducer = l1tMETPFProducer.clone() - from L1Trigger.L1CaloTrigger.l1tPhase2CaloToCorrelatorTM18_cfi import l1tPhase2CaloToCorrelatorTM18 process.l1tPhase2CaloToCorrelatorTM18 = l1tPhase2CaloToCorrelatorTM18.clone() @@ -93,23 +82,8 @@ process.l1tPhase2CaloPFClusterEmulator, process.l1tPhase2GCTBarrelToCorrelatorLayer1Emulator, process.l1tPhase2CaloToCorrelatorTM18, - process.l1tSAMuonsGmt, - process.l1tGTTInputProducer, - process.l1tTrackSelectionProducer, - process.l1tVertexFinderEmulator, - process.L1TLayer1TaskInputsTask, - process.L1TLayer2EGTask, - process.l1tMETPFProducer) - -process.centralGen = cms.EDFilter("CandPtrSelector", src = cms.InputTag("genParticlesForMETAllVisible"), cut = cms.string("abs(eta) < 2.4")) -process.barrelGen = cms.EDFilter("CandPtrSelector", src = cms.InputTag("genParticlesForMETAllVisible"), cut = cms.string("abs(eta) < 1.5")) -process.genMetCentralTrue = process.genMetTrue.clone(src = cms.InputTag("centralGen")) -process.L1TInputTask.add( - process.genParticlesForMETAllVisible, - process.centralGen, - process.barrelGen, - process.genMetCentralTrue -) + process.l1tSAMuonsGmt) + from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter l1ctLayer2SCJetsProducts = cms.VPSet([cms.PSet(jets = cms.InputTag("l1tSC4PFL1PuppiCorrectedEmulator"), @@ -169,7 +143,7 @@ nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), nMu = cms.uint32(2), - tmux6GCTinput = cms.bool(True), + tmux6GCTinput = cms.bool(False), ) process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 From 09cd981c234ecc1aa860e35cf56ce0045daaf1fa Mon Sep 17 00:00:00 2001 From: Gianluca Date: Wed, 6 May 2026 15:32:08 +0200 Subject: [PATCH 60/92] Fix cluster reference --- .../Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index a842cae4391c3..4a26852e717be 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -143,7 +143,7 @@ nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), nMu = cms.uint32(2), - tmux6GCTinput = cms.bool(False), + tmux6GCTinput = cms.bool(True), ) process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 From eece1ceba61f550d5a296938fc94c2cc427f73f8 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Wed, 6 May 2026 15:58:07 +0200 Subject: [PATCH 61/92] Fix handling of newly added data-members in copy and move operations --- L1Trigger/Phase2L1ParticleFlow/src/corrector.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc index 63c62b744e266..6e295df0881e9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc @@ -276,7 +276,9 @@ l1tpf::corrector::corrector(corrector &&corr) neta_(corr.neta_), nemf_(corr.nemf_), emfMax_(corr.emfMax_), - emulate_(corr.emulate_) { + emulate_(corr.emulate_), + debug_(corr.debug_), + emulationMode_(corr.emulationMode_) { } l1tpf::corrector &l1tpf::corrector::operator=(corrector &&corr) { @@ -285,6 +287,8 @@ l1tpf::corrector &l1tpf::corrector::operator=(corrector &&corr) { std::swap(nemf_, corr.nemf_); std::swap(emfMax_, corr.emfMax_); std::swap(emulate_, corr.emulate_); + std::swap(debug_, corr.debug_); + std::swap(emulationMode_, corr.emulationMode_); #ifdef L1PF_USE_ROOT index_.swap(corr.index_); @@ -402,7 +406,7 @@ float l1tpf::corrector::correctedPt(float pt, float emPt, float eta) const { ptcorr = ptcorr * pt; } if (debug_) - dbgCout() << "[EMU] ieta: " << ieta << " iemf: " << iemf << " ipt: " << ipt - 1 + dbgCout() << "[EMU] this: " << this << " ieta: " << ieta << " iemf: " << iemf << " ipt: " << ipt - 1 << "corr: " << hist->GetBinContent(ipt) << " ptcorr: " << ptcorr << std::endl; } return ptcorr; From 587dd9387460ad27a424359dc9d70cdf42158f9a Mon Sep 17 00:00:00 2001 From: Gianluca Date: Wed, 6 May 2026 16:10:55 +0200 Subject: [PATCH 62/92] Temporarily disable serenity barrel pattern files --- .../Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 4a26852e717be..4c66e0578c771 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -189,8 +189,8 @@ barrelWriterDebugPFOutConfigsAPx, barrelWriterDebugEGConfigsAPx ) - process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) - process.l1tLayer1BarrelSerenityElliptic.patternWriters = cms.untracked.VPSet(*barrelSerenityTM18WriterConfigs) + # 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) From 31610932936d012e586f9406e68058b27470ab67 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Mon, 11 May 2026 04:00:32 -0500 Subject: [PATCH 63/92] add missing algorithm include (#27) --- .../Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h | 1 + 1 file changed, 1 insertion(+) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h index 9e1c7b364514c..f0cc0f735ca5c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h @@ -3,6 +3,7 @@ #include #include +#include #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" From 49106998760d01264bc1da6498fa06a0d90cd0fb Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 12 May 2026 12:00:34 +0200 Subject: [PATCH 64/92] Fix eta conversion in digitization GCT EM cluster --- L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 53abf57508bf2..e5ad276b781d8 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1278,7 +1278,7 @@ namespace p2eg { abseta = globalClusteriEta() - n_towers_cardEta * CRYSTALS_IN_TOWER_ETA; // 0 to 84 spare = 4; } else { - abseta = n_towers_cardEta * CRYSTALS_IN_TOWER_ETA + 1 - globalClusteriEta(); // 84 to 0 + abseta = n_towers_cardEta * CRYSTALS_IN_TOWER_ETA - globalClusteriEta() - 1; // 84 to 0 spare = 0; } From 60ef1e05e38f7181c44e775220b499082eed33bd Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 15 May 2026 11:57:15 +0200 Subject: [PATCH 65/92] Fix relative isolation for EM clusters --- .../interface/Phase2L1CaloEGammaUtils.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index e5ad276b781d8..2b7b7705237ac 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1314,12 +1314,10 @@ namespace p2eg { (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); // normalize relIso to 0x3F - int relIso_int = 0; - if (et > iso && et > 0) { - relIso_int = (int)(iso * 63 / et); - } else { - relIso_int = 63; - } + float reliso_f = isoFloat() * 4.0f / etFloat() ; // LSB = 16/64 to compress the useful range (0-16) in 6 bits + // implement saturation + if (reliso_f < 0.0f) reliso_f = 0.0f; + if (reliso_f > 63.0f) reliso_f = 63.0f; // normalize hoe to 0x3F int hoe_int = (int)(hoe * 63 / 15); @@ -1329,7 +1327,7 @@ namespace p2eg { abseta, phivscenter, ap_uint<6>(hoe_int & 0x3F), - ap_uint<6>(relIso_int & 0x3F), + ap_uint<6>(reliso_f + 0.5f), // rounding ap_uint<6>(shape), ap_uint<3>(quality), ap_uint<5>(timing), From d4cc97c1a5b594127fdd7d437fcabb2518911212 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Fri, 15 May 2026 11:42:22 +0200 Subject: [PATCH 66/92] GCT EM correction file from Federica/Piero --- .../data/emcorr_barrel.root | Bin 0 -> 12404 bytes .../python/l1ctLayer1_cff.py | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root diff --git a/L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root b/L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root new file mode 100644 index 0000000000000000000000000000000000000000..b2524f173f48a0dcf8aef0f7a5daca37cbe5f260 GIT binary patch literal 12404 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 literal 0 HcmV?d00001 diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 059b437b975ec..17ea514ea0543 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -43,8 +43,7 @@ muonInputConversionAlgo = cms.string("Emulator"), gctEmInputConversionAlgo = cms.string("Emulator"), gctEmInputConversionParameters = cms.PSet( - # gctEmCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root"), - gctEmCorrector = cms.string(""), + gctEmCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root"), gctEmResol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), offset = cms.vdouble( 0.873, 1.081, 1.563), From baccb7553942544c3566cb1badddff788f6b951e Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 19 May 2026 10:26:16 +0200 Subject: [PATCH 67/92] Fix showershape rounding --- L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 2b7b7705237ac..f6cd9d639c676 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1244,6 +1244,9 @@ namespace p2eg { params["trkMatchWP_isolation"] = is_looseTkiso; caloCrystalCluster.setExperimentalParams(params); + std::cout << "[CaloCrystalCluster] pt: " << caloCrystalCluster.pt() << ", eta: " << caloCrystalCluster.eta() << ", phi: " << caloCrystalCluster.phi() + << " isolation: " << caloCrystalCluster.isolation() << " relIso: " << relIsoFloat() << " iso/pt: " << caloCrystalCluster.isolation()/caloCrystalCluster.pt() << std::endl; + std::cout << "is_iso: " << is_iso << " is_looseTkiso: " << is_looseTkiso << " is_ss: " << is_ss << " is_looseTkss: " << is_looseTkss << std::endl; return caloCrystalCluster; } @@ -1309,7 +1312,7 @@ namespace p2eg { spare = spare | 1; } - ap_uint<6> shape = (0x3F * et2x5 / et5x5); // normalize to 0x3F + ap_uint<6> shape = (64 * et2x5 / et5x5) + 0.5f ; // normalize to 0x3F ap_uint<3> quality = (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); From 6114a019f370c42da8ddf76e146be6c95547a799 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 19 May 2026 10:50:57 +0200 Subject: [PATCH 68/92] Temporary workaround for iso variable --- .../src/egamma/pftkegalgo_ref.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index 758995fed5e4f..a692b0770ab75 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -375,14 +375,19 @@ id_score_t l1ct::TkEgCID_EB_v1::compute_score(const CompositeCandidate &cand, // Prepare the input features // NOTE: this could be computed once per cluster and passed directly to the function ap_ufixed<16, 0> tk_invPt = l1ct::invert_with_shift, 1024>(tk.hwPt); - + constexpr std::array chi2RPhiBins = { {0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 10.0, 15.0, 20.0, 35.0, 60.0, 200.0}}; float cl_pt = calo.floatPt(); //This two ratios will be computed in the calotrigger and passed to the CTL1 in 6 bits - float cl_ss = emcalo[cand.cluster_idx].hwShowerShape.to_float(); - float cl_relIso = emcalo[cand.cluster_idx].hwRelIso.to_float(); + float cl_ss = calo.hwShowerShape.to_float(); + + // FIXME: this is a workaround as the training was erronously done with this variable + ap_ufixed<16, 0> calo_invPt = l1ct::invert_with_shift, 1024>(calo.hwPt); + float reliso_hack = calo.floatRelIso() * calo_invPt.to_float(); + l1ct::rel_iso_t hw_reliso_hack = l1ct::Scales::makeRelIso(reliso_hack); + float cl_relIso = hw_reliso_hack.to_float(); float cl_staWP = calo.hwEmID & 0x1; float cl_looseTkWP = (calo.hwEmID & 0x2) == 0x2; float tk_chi2RPhi = chi2RPhiBins[tk.hwRedChi2RPhi.to_int()]; From 8d467d12763495280a2be8d8de8258129d8d2215 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 26 May 2026 17:24:16 +0200 Subject: [PATCH 69/92] Call L1Candidate constructor and fix eta for negative values --- .../plugins/Phase2L1CaloPFClusterEmulator.cc | 9 ++------- .../Phase2L1TCaloBarrelToCorrelator.cc | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc index cf6e7bf70f60c..70fce6e2c7447 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc @@ -170,13 +170,8 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event int gctphi = tempPfclusters.GCTpfclusters[i].phi; float towereta = realEta[gcteta][gctphi]; float towerphi = realPhi[gcteta][gctphi]; - l1tp2::CaloPFCluster l1CaloPFCluster; - l1CaloPFCluster.setClusterEt(tempPfclusters.GCTpfclusters[i].et); - l1CaloPFCluster.setEcalEt(tempPfclusters.GCTpfclusters[i].ecal); - l1CaloPFCluster.setClusterIEta(gcteta); - l1CaloPFCluster.setClusterIPhi(gctphi); - l1CaloPFCluster.setClusterEta(towereta); - l1CaloPFCluster.setClusterPhi(towerphi); + reco::Particle::PolarLorentzVector clusterP4(tempPfclusters.GCTpfclusters[i].et, towereta, towerphi, 0); + l1tp2::CaloPFCluster l1CaloPFCluster(clusterP4, tempPfclusters.GCTpfclusters[i].et, tempPfclusters.GCTpfclusters[i].ecal, gcteta, gctphi, towereta, towerphi); pfclusterCands->push_back(l1CaloPFCluster); } } diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index d8108261b9ffa..b577f9182047f 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -240,7 +240,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Repeat for PF Clusters for (size_t iCluster = 0; iCluster < inputPFClusters->size(); ++iCluster) { - l1tp2::CaloPFCluster pfIn = inputPFClusters->at(iCluster); + const l1tp2::CaloPFCluster & pfIn = inputPFClusters->at(iCluster); // Skip zero-energy clusters if (pfIn.clusterEt() == 0) @@ -251,7 +251,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 4)) { // only unique region // For PFClusters, the method clusterEta returns a float, so we need to digitize this - float eta_LSB = p2eg::ECAL_eta_range / (p2eg::N_GCTTOWERS_FIBER * p2eg::CRYSTALS_IN_TOWER_ETA); + static const float eta_LSB = p2eg::ECAL_eta_range / (p2eg::N_GCTTOWERS_FIBER * p2eg::CRYSTALS_IN_TOWER_ETA); int temp_iEta_signed = std::floor(pfIn.clusterEta() / eta_LSB); // Default value (for positive eta) int iEta = temp_iEta_signed; @@ -266,8 +266,20 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E if (iEta > maxEta) { continue; } - - ap_uint<7> pf_eta = (ap_uint<7>)((abs(pfIn.clusterEta()) - (eta_LSB / 2)) / eta_LSB); + ap_uint<7> pf_eta = (ap_uint<7>)((std::abs(pfIn.clusterEta())/ eta_LSB)); + // std::cout << "[GCT] PF Cluster: eta in =" << pfIn.clusterEta() + // << " abs: " << std::abs(pfIn.clusterEta()) + // << " ratio: " << std::abs(pfIn.clusterEta())/ eta_LSB + // << " floor: " << std::floor(std::abs(pfIn.clusterEta())/ eta_LSB) + // << " rounded: " << std::floor(( std::abs(pfIn.clusterEta())/ eta_LSB) + 0.5) + // << ", eta out=" << pf_eta.to_int() + // << " float: " << pf_eta * eta_LSB + // << " ieta: " << iEta + // << " (f) " << iEta * eta_LSB + // << " LSB: " << eta_LSB + // << " diff: " << std::abs(std::abs(pfIn.clusterEta()) - (pf_eta * eta_LSB))/ eta_LSB + // << std::endl; + ap_int<7> pf_phi = 0x7F & int(std::floor(phiDifference)); // greatest integer <= x // Initialize the new cluster From cfedaba0a29ea4514baee7b733d35a6e28f77389 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 26 May 2026 17:25:25 +0200 Subject: [PATCH 70/92] Improve workaround --- L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index a692b0770ab75..c51f3babf0679 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -385,7 +385,8 @@ id_score_t l1ct::TkEgCID_EB_v1::compute_score(const CompositeCandidate &cand, // FIXME: this is a workaround as the training was erronously done with this variable ap_ufixed<16, 0> calo_invPt = l1ct::invert_with_shift, 1024>(calo.hwPt); - float reliso_hack = calo.floatRelIso() * calo_invPt.to_float(); + float reliso_hack = calo.hwPt == 1 ? calo.floatRelIso() : calo.floatRelIso() * calo_invPt.to_float(); + l1ct::rel_iso_t hw_reliso_hack = l1ct::Scales::makeRelIso(reliso_hack); float cl_relIso = hw_reliso_hack.to_float(); float cl_staWP = calo.hwEmID & 0x1; From 2b6a0ad3edd35e3014337e878119ee9dc1e61d5f Mon Sep 17 00:00:00 2001 From: Gianluca Date: Thu, 7 May 2026 17:19:15 +0200 Subject: [PATCH 71/92] Implement GT link as per interface document and adapt routing for new GCT @ TMUX18 Fix link filling adapt routing to new GCT link configuration @ TMUX18 --- .../middle_buffer_multififo_regionizer_ref.h | 32 +--- ...middle_buffer_multififo_regionizer_ref.cpp | 157 +++++++++--------- .../test/make_l1ct_binaryFiles_cfg.py | 11 +- 3 files changed, 79 insertions(+), 121 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h index b140408a231bd..420d5caa356dd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/middle_buffer_multififo_regionizer_ref.h @@ -22,8 +22,7 @@ namespace l1ct { bool streaming, unsigned int outii, unsigned int pauseii, - bool useAlsoVtxCoords, - bool tmux6GCTinput = false); + bool useAlsoVtxCoords); // note: this one will work only in CMSSW MiddleBufferMultififoRegionizerEmulator(const edm::ParameterSet& iConfig); @@ -97,7 +96,7 @@ namespace l1ct { to.src = from.src; } - void convert_GCTinput_tmux(const RegionizerDecodedInputs& in_tm6, RegionizerDecodedInputs& in_tm18) const; + // void convert_GCTinput_tmux(const RegionizerDecodedInputs& in_tm6, RegionizerDecodedInputs& in_tm18) const; void init_GCT_tmux18sectors(std::vector>& gct_tmux18_hadcalo, std::vector>& gct_tmux18_emcalo) const; @@ -109,7 +108,6 @@ namespace l1ct { bool streaming_; bool init_; unsigned int iclock_; - bool tmux6GCTinput_; std::vector mergedRegions_, outputRegions_; multififo_regionizer::Regionizer tkRegionizerPre_, tkRegionizerPost_; multififo_regionizer::Regionizer commonCaloRegionizerPre_; @@ -121,7 +119,6 @@ namespace l1ct { std::vector> hadCaloBuffers_; std::vector> emCaloBuffers_; std::vector> muBuffers_; - std::vector gct_slr_regions_; std::vector> gct_tmux18_hadcalo_; std::vector> gct_tmux18_emcalo_; @@ -138,31 +135,6 @@ namespace l1ct { std::vector& valid); void run_worker(const RegionizerDecodedInputs& in, std::vector& out); - void init_GCT_slrs(std::vector& gct_slr_regions) const; - - template - void convert_GCTsector_tmux(const std::vector>& tm6_sectors, - std::vector>& tm18_sectors) const { - static constexpr std::array gct_slr_tmux18sector_mapping = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2}; - for (const auto& sec : tm6_sectors) { - // std::cout << "Processing TMUX6 hadcalo sector: " << isec << " #cl: " << sec.obj.size() << std::endl; - for (auto cl : sec.obj) { - if (cl.hwPt == 0) - continue; // skip empty objects - glbeta_t gl_hweta = sec.region.hwGlbEta(cl.hwEta); - glbphi_t gl_hwphi = sec.region.hwGlbPhi(cl.hwPhi); - for (unsigned int islr = 0; islr < gct_slr_regions_.size(); ++islr) { - if (gct_slr_regions_[islr].containsHw(gl_hweta, gl_hwphi)) { - auto itmux18 = gct_slr_tmux18sector_mapping[islr]; - cl.hwEta = l1ct::Scales::makeEta(tm18_sectors[itmux18].region.localEta(sec.region.floatGlbEtaOf(cl))); - cl.hwPhi = l1ct::Scales::makePhi(tm18_sectors[itmux18].region.localPhi(sec.region.floatGlbPhiOf(cl))); - tm18_sectors[itmux18].obj.push_back(cl); - break; - } - } - } - } - } }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp index a9ff9410b42e0..f992c032575b7 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp @@ -25,8 +25,7 @@ l1ct::MiddleBufferMultififoRegionizerEmulator::MiddleBufferMultififoRegionizerEm /*streaming=*/true, /*outii=*/2, /*pauseii=*/1, - iConfig.getParameter("useAlsoVtxCoords"), - iConfig.getParameter("tmux6GCTinput")) { + iConfig.getParameter("useAlsoVtxCoords")) { debug_ = iConfig.getUntrackedParameter("debug", false); } @@ -43,7 +42,6 @@ edm::ParameterSetDescription l1ct::MiddleBufferMultififoRegionizerEmulator::getP description.add("nEmCalo", 12); description.add("nMu", 2); description.add("useAlsoVtxCoords", true); - description.add("tmux6GCTinput", false); description.addUntracked("debug", false); return description; } @@ -63,8 +61,7 @@ l1ct::MiddleBufferMultififoRegionizerEmulator::MiddleBufferMultififoRegionizerEm bool streaming, unsigned int outii, unsigned int pauseii, - bool useAlsoVtxCoords, - bool tmux6GCTinput) + bool useAlsoVtxCoords) : RegionizerEmulator(useAlsoVtxCoords), NTK_SECTORS(9), NCALO_SECTORS(3), @@ -86,7 +83,6 @@ l1ct::MiddleBufferMultififoRegionizerEmulator::MiddleBufferMultififoRegionizerEm streaming_(streaming), init_(false), iclock_(0), - tmux6GCTinput_(tmux6GCTinput), tkRegionizerPre_(ntk, ntk, false, outii, pauseii, useAlsoVtxCoords), tkRegionizerPost_(ntk, (ntk + outii - 1) / outii, true, outii, pauseii, useAlsoVtxCoords), commonCaloRegionizerPre_(ncalo, ncalo, false, outii, pauseii), @@ -124,14 +120,16 @@ l1ct::MiddleBufferMultififoRegionizerEmulator::MiddleBufferMultififoRegionizerEm for (unsigned int j = 0; j < 3; ++j) { // 3 regions x sector for (unsigned int il = 0; il < HCAL_LINKS; ++il) { caloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il); - if (j != 2) { - caloRoutes_.emplace_back((is + 2) % 3, il, 3 * is + j + phisectors * ie, il + HCAL_LINKS); + if (j != 1) { + const unsigned int from_sector = (is + (j == 2 ? 1 : 2)) % NCALO_SECTORS; + caloRoutes_.emplace_back(from_sector, il, 3 * is + j + phisectors * ie, il + HCAL_LINKS); } } for (unsigned int il = 0; il < ECAL_LINKS; ++il) { emCaloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il); - if (j != 2) { - emCaloRoutes_.emplace_back((is + 2) % 3, il, 3 * is + j + phisectors * ie, il + ECAL_LINKS); + if (j != 1) { + const unsigned int from_sector = (is + (j == 2 ? 1 : 2)) % NCALO_SECTORS; + emCaloRoutes_.emplace_back(from_sector, il, 3 * is + j + phisectors * ie, il + ECAL_LINKS); } } } @@ -143,8 +141,6 @@ l1ct::MiddleBufferMultififoRegionizerEmulator::MiddleBufferMultififoRegionizerEm muRoutes_.emplace_back(0, il, j, il); } } - - init_GCT_slrs(gct_slr_regions_); } l1ct::MiddleBufferMultififoRegionizerEmulator::~MiddleBufferMultififoRegionizerEmulator() {} @@ -231,24 +227,28 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::initSectorsAndRegions(const tkRegionizerPost_.initRegions(out); } if (ncalo_) { - assert(in.hadcalo.size() == NCALO_SECTORS); + assert(in.hadcalo.size() == NCALO_SECTORS * 4); + + // we will map the decoded sectors (matching GTC SLRs x 2 eta) into the 3 link sectors + init_GCT_tmux18sectors(gct_tmux18_hadcalo_, gct_tmux18_emcalo_); + std::vector> commonCaloSectors(NCALO_SECTORS); for (unsigned int isec = 0; isec != NCALO_SECTORS; isec++) { - commonCaloSectors[isec].region = in.hadcalo[isec].region; + commonCaloSectors[isec].region = gct_tmux18_hadcalo_[isec].region; } commonCaloRegionizerPre_.initSectors(commonCaloSectors); commonCaloRegionizerPre_.initRegions(mergedRegions); commonCaloRegionizerPre_.initRouting(caloRoutes_); - hadCaloRegionizerPre_.initSectors(in.hadcalo); + hadCaloRegionizerPre_.initSectors(gct_tmux18_hadcalo_); hadCaloRegionizerPre_.initRegions(mergedRegions); if (ECAL_LINKS) hadCaloRegionizerPre_.initRouting(caloRoutes_); hadCaloRegionizerPost_.initRegions(out); } if (nem_) { - assert(in.emcalo.size() == NCALO_SECTORS); - emCaloRegionizerPre_.initSectors(in.emcalo); + assert(in.emcalo.size() == NCALO_SECTORS * 4); + emCaloRegionizerPre_.initSectors(gct_tmux18_emcalo_); emCaloRegionizerPre_.initRegions(mergedRegions); if (ECAL_LINKS) emCaloRegionizerPre_.initRouting(emCaloRoutes_); @@ -480,26 +480,68 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::fillSharedCaloLinks( const std::vector>& had_in, std::vector& links, std::vector& valid) { - // FIXME: the link filling should be done according to TMUX18 GCT-CTL1 interface document assert(ECAL_LINKS == 0 && HCAL_LINKS == 1 && ncalo_ != 0 && nem_ != 0); links.resize(NCALO_SECTORS); valid.resize(links.size()); - // for the moment we assume the first 54 clocks are for EM, the rest for HAD - const unsigned int NCLK_EM = 54; + + // input calo sectors map to GCT SLRs. We can use this to fill the links according to the interface document. + // while filling we also convert to the "link sector" coordinates + const unsigned int NEM_WORDS = 16; + const unsigned int NHAD_WORDS = 24; + + const std::vector gct_slr_tmux18sector_mapping = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2}; + const std::vector slr_order_per_link = {7, 1, 6, 0}; + for (unsigned int is = 0; is < NCALO_SECTORS; ++is) { links[is].clear(); - if (iclock < NCLK_EM) { - valid[is] = true; - if (iclock < em_in[is].size()) { - encode(em_in[is][iclock], links[is]); + if (iclock == 0 || iclock == 81) { + valid[is] = false; + continue; // technical words -> ignored + } + unsigned int rel_pos = (iclock) % 81; + if ((rel_pos - 1) < 2 * NEM_WORDS) { // EM clusters + unsigned int islr = ((rel_pos - 1) < NEM_WORDS) ? 0 : 1; + if (iclock > 81) islr += 2; + unsigned int insec = slr_order_per_link[islr] + is * 2; + unsigned int itmux18 = gct_slr_tmux18sector_mapping[insec]; + const auto& sec = em_in[insec]; + unsigned int rel_em = (rel_pos - 1) % (NEM_WORDS); + if (rel_em < sec.size()) { + auto cl = sec[rel_em]; + if(!gct_tmux18_emcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { + assert(false && "EM calo cluster out of TMUX18 sector bounds!"); + } + + // convert to TMUX18 sector coordinates + cl.hwEta = l1ct::Scales::makeEta(gct_tmux18_emcalo_[itmux18].region.localEta(sec.region.floatGlbEtaOf(cl))); + cl.hwPhi = l1ct::Scales::makePhi(gct_tmux18_emcalo_[itmux18].region.localPhi(sec.region.floatGlbPhiOf(cl))); + encode(cl, links[is]); + valid[is] = true; + } else { + valid[is] = false; } - } else { - if (iclock - NCLK_EM < had_in[is].size()) { - encode(had_in[is][iclock - NCLK_EM], links[is]); + } else if ((rel_pos - 1) >= 2 * NEM_WORDS && (rel_pos - 1) < (2 * NEM_WORDS + 2 * NHAD_WORDS)) { // Had clusters + unsigned int islr = ((rel_pos - 1 - 2 * NEM_WORDS) < NHAD_WORDS) ? 0 : 1; + if (iclock > 81) islr += 2; + unsigned int insec = slr_order_per_link[islr] + is * 2; + unsigned int itmux18 = gct_slr_tmux18sector_mapping[insec]; + const auto& sec = had_in[insec]; + unsigned int rel_had = (rel_pos - 1 - 2 * NEM_WORDS) % NHAD_WORDS; + if (rel_had < sec.size()) { + auto cl = sec[rel_had]; + // convert to TMUX18 sector coordinates + if(!gct_tmux18_hadcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { + assert(false && "Had calo cluster out of TMUX18 sector bounds!"); + } + cl.hwEta = l1ct::Scales::makeEta(gct_tmux18_hadcalo_[itmux18].region.localEta(sec.region.floatGlbEtaOf(cl))); + cl.hwPhi = l1ct::Scales::makePhi(gct_tmux18_hadcalo_[itmux18].region.localPhi(sec.region.floatGlbPhiOf(cl))); + encode(cl, links[is]); valid[is] = true; } else { valid[is] = false; } + } else { + valid[is] = false; } } // sectors } @@ -590,29 +632,17 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::reset() { b.reset(); } -void l1ct::MiddleBufferMultififoRegionizerEmulator::convert_GCTinput_tmux(const RegionizerDecodedInputs& in_tm6, - RegionizerDecodedInputs& in_tm18) const { - for (auto& sec : in_tm18.hadcalo) - sec.clear(); - - for (auto& sec : in_tm18.emcalo) - sec.clear(); - - convert_GCTsector_tmux(in_tm6.hadcalo, in_tm18.hadcalo); - convert_GCTsector_tmux(in_tm6.emcalo, in_tm18.emcalo); -} - void l1ct::MiddleBufferMultififoRegionizerEmulator::init_GCT_tmux18sectors( std::vector>& gct_tmux18_hadcalo, std::vector>& gct_tmux18_emcalo) const { std::vector etaBoundaries = {-1.5, 1.5}; - unsigned int phiSlices = 3; + const unsigned int phiSlices = 3; // if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) // throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n"); - float phiWidth = 2 * M_PI / phiSlices; + const float phiWidth = 2 * M_PI / phiSlices; // if (phiWidth > 2 * l1ct::Scales::maxAbsPhi()) // throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type"); - float phiZero = M_PI * 7 / 18; + float phiZero = M_PI * 4 / 18; for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { // float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta]; // if (etaWidth > 2 * l1ct::Scales::maxAbsEta()) @@ -635,50 +665,13 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::init_GCT_tmux18sectors( } } -void l1ct::MiddleBufferMultififoRegionizerEmulator::init_GCT_slrs( - std::vector& gct_slr_regions) const { - // We Initialize GCT SLR regions (dividing them in eta +- to be able to assign clusters to the correct link and sector - std::vector etaBoundaries = {-1.5, 0, 1.5}; - unsigned int phiSlices = 6; - // if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) - // throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n"); - float phiWidth = 2 * M_PI / phiSlices; - // if (phiWidth > 2 * l1ct::Scales::maxAbsPhi()) - // throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type"); - float phiZero = M_PI * 4 / 18; - for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { - // float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta]; - // if (etaWidth > 2 * l1ct::Scales::maxAbsEta()) - // throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); - for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { - float phiCenter = reduceRange(iphi * phiWidth + phiZero); - gct_slr_regions.emplace_back(etaBoundaries[ieta], - etaBoundaries[ieta + 1], - phiCenter, - phiWidth, - 0, // no extra - 0); // no extra - } - } -} void l1ct::MiddleBufferMultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { - if (tmux6GCTinput_) { - if (!init_) { - init_GCT_tmux18sectors(gct_tmux18_hadcalo_, gct_tmux18_emcalo_); - } - RegionizerDecodedInputs in_tm18; - in_tm18.track = in.track; - in_tm18.muon = in.muon; - in_tm18.hadcalo = gct_tmux18_hadcalo_; - in_tm18.emcalo = gct_tmux18_emcalo_; - convert_GCTinput_tmux(in, in_tm18); - run_worker(in_tm18, out); - } else { - run_worker(in, out); - } + // FIXME: run_worker is no longer needed + run_worker(in, out); } +// FIXME: run_worker is no longer needed void l1ct::MiddleBufferMultififoRegionizerEmulator::run_worker(const RegionizerDecodedInputs& in, std::vector& out) { assert(streaming_); // doesn't make sense otherwise diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 4c66e0578c771..e8418ed64f3a5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -142,8 +142,7 @@ nTrack = cms.uint32(22), nCalo = cms.uint32(15), nEmCalo = cms.uint32(12), - nMu = cms.uint32(2), - tmux6GCTinput = cms.bool(True), + nMu = cms.uint32(2) ) process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 @@ -153,13 +152,7 @@ process.l1tLayer1BarrelSerenity.puAlgoParameters.nIn = 27 process.l1tLayer1BarrelSerenity.puAlgoParameters.nOut = 27 process.l1tLayer1BarrelSerenity.puAlgoParameters.finalSortAlgo = "FoldedHybrid" -process.l1tLayer1BarrelSerenity.caloSectors = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-1.5, 0, 1.5), - phiSlices = cms.uint32(3), - phiZero = cms.double(math.pi/18) - ), -) + 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( From 272d3abbaebd28bb49bdc2ae952c794fb1db2bcf Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 29 May 2026 14:35:40 +0200 Subject: [PATCH 72/92] Remove debug verbosity --- L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index f6cd9d639c676..a96e959db46f4 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1244,9 +1244,6 @@ namespace p2eg { params["trkMatchWP_isolation"] = is_looseTkiso; caloCrystalCluster.setExperimentalParams(params); - std::cout << "[CaloCrystalCluster] pt: " << caloCrystalCluster.pt() << ", eta: " << caloCrystalCluster.eta() << ", phi: " << caloCrystalCluster.phi() - << " isolation: " << caloCrystalCluster.isolation() << " relIso: " << relIsoFloat() << " iso/pt: " << caloCrystalCluster.isolation()/caloCrystalCluster.pt() << std::endl; - std::cout << "is_iso: " << is_iso << " is_looseTkiso: " << is_looseTkiso << " is_ss: " << is_ss << " is_looseTkss: " << is_looseTkss << std::endl; return caloCrystalCluster; } From 07f90d6442366aa2982568d834e89fc71e395690 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 29 May 2026 14:49:36 +0200 Subject: [PATCH 73/92] code format --- .../Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp | 6 +++--- .../middle_buffer_multififo_regionizer_ref.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index c51f3babf0679..93f79cc72963d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -375,7 +375,7 @@ id_score_t l1ct::TkEgCID_EB_v1::compute_score(const CompositeCandidate &cand, // Prepare the input features // NOTE: this could be computed once per cluster and passed directly to the function ap_ufixed<16, 0> tk_invPt = l1ct::invert_with_shift, 1024>(tk.hwPt); - + constexpr std::array chi2RPhiBins = { {0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 10.0, 15.0, 20.0, 35.0, 60.0, 200.0}}; @@ -386,9 +386,9 @@ id_score_t l1ct::TkEgCID_EB_v1::compute_score(const CompositeCandidate &cand, // FIXME: this is a workaround as the training was erronously done with this variable ap_ufixed<16, 0> calo_invPt = l1ct::invert_with_shift, 1024>(calo.hwPt); float reliso_hack = calo.hwPt == 1 ? calo.floatRelIso() : calo.floatRelIso() * calo_invPt.to_float(); - + l1ct::rel_iso_t hw_reliso_hack = l1ct::Scales::makeRelIso(reliso_hack); - float cl_relIso = hw_reliso_hack.to_float(); + float cl_relIso = hw_reliso_hack.to_float(); float cl_staWP = calo.hwEmID & 0x1; float cl_looseTkWP = (calo.hwEmID & 0x2) == 0x2; float tk_chi2RPhi = chi2RPhiBins[tk.hwRedChi2RPhi.to_int()]; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp index f992c032575b7..be15dcaffe78a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp @@ -501,14 +501,15 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::fillSharedCaloLinks( unsigned int rel_pos = (iclock) % 81; if ((rel_pos - 1) < 2 * NEM_WORDS) { // EM clusters unsigned int islr = ((rel_pos - 1) < NEM_WORDS) ? 0 : 1; - if (iclock > 81) islr += 2; + if (iclock > 81) + islr += 2; unsigned int insec = slr_order_per_link[islr] + is * 2; unsigned int itmux18 = gct_slr_tmux18sector_mapping[insec]; const auto& sec = em_in[insec]; unsigned int rel_em = (rel_pos - 1) % (NEM_WORDS); if (rel_em < sec.size()) { auto cl = sec[rel_em]; - if(!gct_tmux18_emcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { + if (!gct_tmux18_emcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { assert(false && "EM calo cluster out of TMUX18 sector bounds!"); } @@ -522,7 +523,8 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::fillSharedCaloLinks( } } else if ((rel_pos - 1) >= 2 * NEM_WORDS && (rel_pos - 1) < (2 * NEM_WORDS + 2 * NHAD_WORDS)) { // Had clusters unsigned int islr = ((rel_pos - 1 - 2 * NEM_WORDS) < NHAD_WORDS) ? 0 : 1; - if (iclock > 81) islr += 2; + if (iclock > 81) + islr += 2; unsigned int insec = slr_order_per_link[islr] + is * 2; unsigned int itmux18 = gct_slr_tmux18sector_mapping[insec]; const auto& sec = had_in[insec]; @@ -530,7 +532,7 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::fillSharedCaloLinks( if (rel_had < sec.size()) { auto cl = sec[rel_had]; // convert to TMUX18 sector coordinates - if(!gct_tmux18_hadcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { + if (!gct_tmux18_hadcalo_[itmux18].region.containsHw(sec.region.hwGlbEtaOf(cl), sec.region.hwGlbPhiOf(cl))) { assert(false && "Had calo cluster out of TMUX18 sector bounds!"); } cl.hwEta = l1ct::Scales::makeEta(gct_tmux18_hadcalo_[itmux18].region.localEta(sec.region.floatGlbEtaOf(cl))); From 2ca671be3a33e6181bf9bcedc8ca81b0d0014a09 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Mon, 1 Jun 2026 20:24:58 +0200 Subject: [PATCH 74/92] updated hadronic corrections --- .../data/hadcorr_barrel.root | Bin 38065 -> 38170 bytes .../python/l1ctLayer1_cff.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root index 141cb1897bbeee786dcb0e5591d2a0f9845bc43b..61d1c67595407d577e213beab067ed78ca61572c 100644 GIT binary patch delta 29460 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 diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 17ea514ea0543..0e22048ba8067 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -56,8 +56,8 @@ gctHadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), gctHadResol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 3.757, 3.197, 1.744), - scale = cms.vdouble( 0.175, 0.222, 0.354), + offset = cms.vdouble( 3.904, 3.240, 1.726), + scale = cms.vdouble( 0.162, 0.221, 0.351), kind = cms.string('calo'), ), ), From 436db02192ba1602ba799bdf53fb3a7980d904b5 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Tue, 2 Jun 2026 11:19:37 +0200 Subject: [PATCH 75/92] update tkele EM model --- .../data/egamma/compositeID_EB_v1.1.json | 18499 ++++++++++++++++ .../python/l1TkEgAlgoEmulator_cfi.py | 6 +- .../src/egamma/pftkegalgo_ref.cpp | 8 +- 3 files changed, 18503 insertions(+), 10 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.1.json diff --git a/L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.1.json b/L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.1.json new file mode 100644 index 0000000000000..a45619d3fca7a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.1.json @@ -0,0 +1,18499 @@ +{ + "n_classes": 2, + "n_features": 11, + "n_trees": 14, + "max_depth": 6, + "init_predict": [ + 0 + ], + "norm": 1, + "library": "xgboost", + "splitting_convention": "<", + "feature_map": { + "TkEle_CryClu_pt": 0, + "TkEle_CryClu_showerShape": 1, + "TkEle_CryClu_relIso": 2, + "TkEle_CryClu_standaloneWP": 3, + "TkEle_CryClu_looseL1TkMatchWP": 4, + "TkEle_Tk_chi2RPhi": 5, + "TkEle_Tk_ptFrac": 6, + "TkEle_PtRatio": 7, + "TkEle_nTkMatch": 8, + "TkEle_absdeta": 9, + "TkEle_absdphi": 10 + }, + "trees": [ + [ + { + "feature": [ + 2, + 10, + 2, + 7, + 6, + 3, + 0, + 0, + 4, + 5, + 3, + 7, + 10, + 2, + -2, + 5, + 1, + 1, + 6, + 6, + 3, + -2, + 7, + 5, + 0, + 7, + 5, + 0, + -2, + 7, + -2, + -2, + 0, + 5, + -2, + 7, + 6, + 7, + 8, + -2, + 6, + -2, + 8, + 10, + 8, + 5, + -2, + 5, + 7, + 6, + 9, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 9, + 0, + 9, + 10, + 7, + -2, + 0, + 9, + -2, + -2, + 6, + -2, + 0, + 1, + 2, + 7, + 7, + 6, + 6, + 5, + 6, + 8, + 6, + 10, + -2, + -2, + -2, + -2, + 10, + 7, + -2, + -2, + 5, + 6, + 10, + 6, + 7, + -2, + -2, + 9, + 6, + 5, + 7, + -2, + 5, + 10, + 2, + 2, + 6, + -2, + 9, + 2, + 9, + 0, + 7, + 0, + 2, + 5, + 7, + 7, + 7, + 0, + 7, + 8, + 10, + 6, + 5, + 9, + -2, + -2, + -2, + -2, + 10, + 6, + 7, + 8, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 6, + -2, + 0, + 9, + 2, + 10, + -2, + -2, + -2, + 10, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + 0, + 6, + 8, + 7, + -2, + 2, + -2, + -2, + -2, + 7, + -2, + -2, + 2, + 1, + 7, + 2, + -2, + 10, + 0, + -2, + 2, + 1, + -2, + -2, + 6, + 0, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + 9, + -2, + 2, + 0, + 0, + 4, + -2, + -2, + -2, + -2, + -2, + 8, + -2, + 0, + 0, + 1, + -2, + 8, + 2, + -2, + 9, + -2, + -2, + -2, + -2, + 8, + 6, + -2, + 2, + 6, + -2, + -2, + -2, + -2, + 2, + -2, + -2, + 6, + 7, + -2, + -2, + 10, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + 1, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 6, + -2, + -2, + 0, + 7, + -2, + -2, + 7, + 7, + -2, + 0, + -2, + 10, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + 8, + -2, + -2, + 0, + -2, + 0, + 6, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.96875, + -0.84375, + -0.15625, + -0.9453125, + -0.8046875, + 0.0, + -0.609375, + -0.234375, + 0.0, + -0.25, + 0.0, + -0.921875, + -0.84375, + -0.09375, + 0.0, + -0.125, + -0.59375, + 0.84375, + -0.984375, + -0.8671875, + 0.0, + 0.0, + -0.6015625, + -0.125, + -0.3984375, + -0.9453125, + 0.125, + -0.890625, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.390625, + -0.125, + 0.0, + -0.796875, + -0.9765625, + -0.3125, + -0.75, + 0.0, + -0.9921875, + 0.0, + -0.5, + -0.875, + -0.875, + 0.125, + 0.0, + -0.125, + -0.890625, + -0.8515625, + -0.25, + 0.0, + 0.0, + -0.453125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8203125, + 0.0, + -0.75, + -0.6171875, + -0.25, + 0.65625, + 0.2578125, + 0.0, + -0.7578125, + -0.75, + 0.0, + 0.0, + -0.9921875, + 0.0, + -0.9453125, + 0.15625, + -0.34375, + -0.890625, + -0.953125, + -0.9921875, + -0.984375, + 0.375, + -0.90625, + -0.75, + -0.984375, + -0.625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + -0.9296875, + 0.0, + 0.0, + -0.75, + -0.9296875, + -0.40625, + -0.96875, + -0.703125, + 0.0, + 0.0, + 0.25, + -0.9375, + 0.0, + -0.9453125, + 0.0, + 0.25, + 0.125, + -0.6875, + -0.625, + -0.421875, + 0.0, + -0.25, + -0.59375, + 0.25, + -0.828125, + -0.9609375, + -0.828125, + -0.9375, + -0.25, + -0.484375, + -0.7734375, + 0.3828125, + -0.3203125, + -0.6875, + -0.625, + 0.4375, + -0.8046875, + 0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.78125, + -0.9921875, + -0.4609375, + -0.75, + 0.0, + -0.0546875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.890625, + 0.0, + 0.890625, + 0.25, + -0.9375, + -0.6875, + 0.0, + 0.0, + 0.0, + -0.8125, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + -0.203125, + -0.9765625, + -0.5, + -0.875, + 0.0, + -0.9375, + 0.0, + 0.0, + 0.0, + -0.8359375, + 0.0, + 0.0, + -0.9375, + 0.84375, + 0.21875, + -0.9375, + 0.0, + 0.15625, + 0.0, + 0.0, + -0.9375, + 0.84375, + 0.0, + 0.0, + -0.90625, + -0.0703125, + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.7578125, + 0.0, + 0.0, + 0.0, + -0.28125, + -0.8515625, + 0.03125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.625, + 0.0, + 0.953125, + -0.890625, + -0.59375, + 0.0, + -0.75, + -0.9375, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + -0.8359375, + 0.0, + -0.9375, + -0.5625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.0, + -0.546875, + -0.8203125, + 0.0, + 0.0, + -0.28125, + 0.78125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.59375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9140625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.5390625, + -0.625, + 0.0, + 0.0, + -0.6171875, + -0.71875, + 0.0, + -0.1484375, + 0.0, + -0.8125, + -0.2421875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.25, + 0.0, + 0.0, + 0.0, + -0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.796875, + 0.0, + 0.0, + 0.0, + 0.25, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.484375, + 0.0, + -0.25, + 0.0, + 0.0, + 0.1640625, + 0.0, + -0.046875, + -0.96875, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 2305055.0, + 158380.0, + 1237514.75, + 58766.125, + 79135.8594, + 766925.25, + 8216.0, + 5684.61719, + 23553.75, + 139291.281, + 9476.48438, + 106539.5, + 459570.812, + 683.125, + -0.0, + 3011.18774, + 1108.42847, + 1251.43201, + 11673.125, + 10902.709, + 7595.82031, + -0.00826576725, + 4782.6875, + 91528.5312, + 11010.625, + 104334.719, + 106273.0, + 1736.46863, + 1.03898513, + 919.081543, + 0.048687201, + 0.682480574, + 925.487549, + 346.868774, + 0.00195301895, + 7975.625, + 11301.9609, + 7010.26562, + 1827.4646, + -0.0, + 3752.46094, + -0.0, + 557.53125, + 18244.1875, + 19088.6172, + 12161.2812, + -1.06549895, + 14949.1953, + 113632.938, + 50949.3125, + 23938.8828, + -0.0, + 0.587347686, + 371.698242, + -0.0, + -0.0, + 0.464416325, + -0.469251335, + -0.0, + 6424.125, + -0.0, + 4403.17773, + 1672.44531, + 5550.07031, + 1704.37402, + 2302.53198, + -0.0412119813, + 3852.86719, + 2595.75195, + 1.02016151, + -0.0, + 16547.1016, + -0.931873322, + 4039.1543, + 20304.5098, + 6548.28125, + 2379.63721, + 4271.40039, + 2346.86865, + 57197.0938, + 8455.46191, + 958.21875, + 43568.1133, + 8401.92578, + 4460.97266, + -0.604682326, + -0.0, + -0.0, + 1.05794239, + 668.774414, + 805.440063, + -0.0, + 0.830535829, + 3780.6748, + 4414.65625, + 635.558167, + 1811.84473, + 1456.35645, + -0.0, + -0.0, + 1101.03906, + 2672.55273, + 1354.63672, + 10509.0332, + -0.884303033, + 269.678528, + 692.238281, + 2726.28174, + 1422.46484, + 2885.84375, + -0.0, + 157.868393, + 693.983887, + 2677.4043, + 2288.21777, + 796.467773, + 156.275986, + 20183.4688, + 7270.33545, + 4806.85938, + 2995.84814, + 1664.5625, + 16347.2891, + 6737.27832, + 5424.53516, + 961.222656, + 3937.54517, + 213.197205, + 1012.3125, + -0.637472868, + -0.0, + -0.0, + 0.54559797, + 1854.0293, + 1412.37244, + 1700.82812, + 164.094574, + -0.0, + 551.572388, + -0.0, + -0.660353184, + -0.0, + 0.643941045, + 0.955595613, + -0.0, + 0.542923331, + 2356.06055, + -0.0, + 1329.86133, + 7173.60938, + 1687.26099, + 137.08519, + 0.103236005, + 0.483337164, + -0.0, + 122.588745, + 1026.63477, + -0.849157333, + -0.0, + -0.938799441, + -0.0, + -0.0, + -0.147896141, + -0.554565072, + -0.0, + -0.637275934, + -0.0, + 0.0111020412, + -0.361887455, + -0.0, + 0.482104659, + -0.0, + -0.157339722, + 5948.6875, + 4815.4043, + 2192.68506, + 1699.61731, + 435.816406, + -0.0, + 1802.40881, + -0.520152628, + -0.872371316, + -0.0, + 1274.43396, + -0.910227239, + -0.256870866, + 1195.79102, + 2240.37939, + 212.546875, + 498.058594, + -0.0, + 2259.52515, + 1863.38135, + -0.0337351523, + 425.451019, + 1682.15906, + -0.652092993, + -0.0, + 486.99707, + 2966.44873, + 472.805054, + -0.87537086, + -0.0, + -0.0, + -0.213607639, + -0.0, + 0.413109392, + 519.944458, + 0.405365646, + 1697.56445, + -0.0, + 2352.19922, + 2987.70166, + 839.365112, + 1050.17554, + -0.0, + -0.25113371, + -0.0, + -0.123915233, + -0.0, + 149.774414, + -0.0, + 3629.375, + 3699.06445, + 135.15419, + -0.0, + 263.607422, + 2055.95142, + -0.0130916908, + 810.839111, + -0.722568274, + 0.370330662, + -0.0, + -0.341036916, + 677.170959, + 318.767578, + -0.0, + 271.42514, + 1725.41406, + -0.835282207, + -0.0, + 0.691789687, + 0.0300070792, + 1782.05786, + -0.472059637, + -0.0, + 242.200195, + 469.854736, + -0.0, + -0.0, + 607.183594, + 587.973633, + -0.0, + -0.0, + 0.722334445, + -0.36016506, + -0.0, + -0.487454087, + -0.0, + 0.826281428, + -0.0, + -0.613023996, + -0.0, + -0.348744869, + 0.477647841, + 412.017334, + -0.0, + 269.390503, + -0.0, + 0.565476, + -0.0, + 0.915368259, + -0.0, + -0.0, + 1717.64453, + -0.0, + -0.246612325, + -0.0123013603, + -0.637017369, + 509.789062, + -0.0, + -0.0, + 624.549805, + 290.268677, + -0.0, + -0.0, + 357.921875, + 434.327911, + -0.165819153, + 229.021973, + -0.0, + 809.752197, + 2120.55981, + 0.797287285, + -0.0, + 0.393726498, + -0.0, + -0.0, + -0.605781972, + -0.530431807, + -0.0, + -0.0, + 0.460151553, + -0.0, + -0.454007417, + 521.207031, + -0.0, + 0.531960964, + -0.0, + 179.696289, + -0.0, + 0.257505715, + -0.0, + -0.0, + 0.722348928, + -0.0, + 236.857666, + -0.0, + -0.671703815, + -0.0, + 963.997803, + -0.0, + -0.54177326, + 0.556469321, + -0.0, + -0.492361695, + -0.0, + -0.0, + 136.594849, + -0.0, + 983.416016, + -0.0, + 0.362043321, + 768.8125, + -0.0, + 342.186829, + 833.984375, + 0.179183975, + -0.0, + -0.0, + 0.735585093 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + -1, + 29, + 31, + 33, + 35, + 37, + 39, + -1, + 41, + 43, + 45, + 47, + 49, + 51, + -1, + 53, + -1, + -1, + 55, + 57, + -1, + 59, + 61, + 63, + 65, + -1, + 67, + -1, + 69, + 71, + 73, + 75, + -1, + 77, + 79, + 81, + 83, + -1, + -1, + 85, + -1, + -1, + -1, + -1, + -1, + 87, + -1, + 89, + 91, + 93, + 95, + 97, + -1, + 99, + 101, + -1, + -1, + 103, + -1, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + 127, + -1, + -1, + -1, + -1, + 129, + 131, + -1, + -1, + 133, + 135, + 137, + 139, + 141, + -1, + -1, + 143, + 145, + 147, + 149, + -1, + 151, + 153, + 155, + 157, + 159, + -1, + 161, + 163, + 165, + 167, + 169, + 171, + 173, + 175, + 177, + 179, + 181, + 183, + 185, + 187, + 189, + 191, + 193, + 195, + -1, + -1, + -1, + -1, + 197, + 199, + 201, + 203, + -1, + 205, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 207, + -1, + 209, + 211, + 213, + 215, + -1, + -1, + -1, + 217, + 219, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 221, + 223, + 225, + 227, + 229, + -1, + 231, + -1, + -1, + -1, + 233, + -1, + -1, + 235, + 237, + 239, + 241, + -1, + 243, + 245, + -1, + 247, + 249, + -1, + -1, + 251, + 253, + 255, + -1, + -1, + -1, + -1, + -1, + -1, + 257, + -1, + 259, + -1, + 261, + 263, + 265, + 267, + -1, + -1, + -1, + -1, + -1, + 269, + -1, + 271, + 273, + 275, + -1, + 277, + 279, + -1, + 281, + -1, + -1, + -1, + -1, + 283, + 285, + -1, + 287, + 289, + -1, + -1, + -1, + -1, + 291, + -1, + -1, + 293, + 295, + -1, + -1, + 297, + 299, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 301, + -1, + 303, + -1, + -1, + -1, + -1, + -1, + -1, + 305, + -1, + -1, + -1, + -1, + 307, + -1, + -1, + 309, + 311, + -1, + -1, + 313, + 315, + -1, + 317, + -1, + 319, + 321, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 323, + -1, + -1, + -1, + 325, + -1, + -1, + -1, + -1, + -1, + -1, + 327, + -1, + -1, + -1, + 329, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 331, + -1, + 333, + -1, + -1, + 335, + -1, + 337, + 339, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + -1, + 30, + 32, + 34, + 36, + 38, + 40, + -1, + 42, + 44, + 46, + 48, + 50, + 52, + -1, + 54, + -1, + -1, + 56, + 58, + -1, + 60, + 62, + 64, + 66, + -1, + 68, + -1, + 70, + 72, + 74, + 76, + -1, + 78, + 80, + 82, + 84, + -1, + -1, + 86, + -1, + -1, + -1, + -1, + -1, + 88, + -1, + 90, + 92, + 94, + 96, + 98, + -1, + 100, + 102, + -1, + -1, + 104, + -1, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + 128, + -1, + -1, + -1, + -1, + 130, + 132, + -1, + -1, + 134, + 136, + 138, + 140, + 142, + -1, + -1, + 144, + 146, + 148, + 150, + -1, + 152, + 154, + 156, + 158, + 160, + -1, + 162, + 164, + 166, + 168, + 170, + 172, + 174, + 176, + 178, + 180, + 182, + 184, + 186, + 188, + 190, + 192, + 194, + 196, + -1, + -1, + -1, + -1, + 198, + 200, + 202, + 204, + -1, + 206, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 208, + -1, + 210, + 212, + 214, + 216, + -1, + -1, + -1, + 218, + 220, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 222, + 224, + 226, + 228, + 230, + -1, + 232, + -1, + -1, + -1, + 234, + -1, + -1, + 236, + 238, + 240, + 242, + -1, + 244, + 246, + -1, + 248, + 250, + -1, + -1, + 252, + 254, + 256, + -1, + -1, + -1, + -1, + -1, + -1, + 258, + -1, + 260, + -1, + 262, + 264, + 266, + 268, + -1, + -1, + -1, + -1, + -1, + 270, + -1, + 272, + 274, + 276, + -1, + 278, + 280, + -1, + 282, + -1, + -1, + -1, + -1, + 284, + 286, + -1, + 288, + 290, + -1, + -1, + -1, + -1, + 292, + -1, + -1, + 294, + 296, + -1, + -1, + 298, + 300, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 302, + -1, + 304, + -1, + -1, + -1, + -1, + -1, + -1, + 306, + -1, + -1, + -1, + -1, + 308, + -1, + -1, + 310, + 312, + -1, + -1, + 314, + 316, + -1, + 318, + -1, + 320, + 322, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 324, + -1, + -1, + -1, + 326, + -1, + -1, + -1, + -1, + -1, + -1, + 328, + -1, + -1, + -1, + 330, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 332, + -1, + 334, + -1, + -1, + 336, + -1, + 338, + 340, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 2, + 10, + 2, + 7, + 3, + 3, + 0, + 5, + 6, + 5, + 6, + 1, + 10, + 2, + -2, + 0, + 9, + 7, + 4, + -2, + -2, + 5, + 7, + 5, + 6, + 6, + 5, + 0, + -2, + 9, + -2, + -2, + -2, + 0, + -2, + -2, + 7, + 7, + 0, + -2, + -2, + 10, + 7, + 10, + -2, + 0, + 1, + 6, + 9, + 0, + 1, + 10, + -2, + 7, + 4, + -2, + 10, + -2, + 1, + -2, + 6, + 2, + 2, + 2, + -2, + 2, + 2, + 7, + 7, + 2, + 5, + 8, + 8, + 8, + 2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + 0, + 6, + 7, + 5, + 0, + -2, + -2, + -2, + 0, + 9, + 0, + 7, + 5, + 5, + -2, + 0, + 5, + 7, + 9, + 7, + 5, + -2, + -2, + 6, + -2, + 7, + 7, + 10, + 6, + 1, + -2, + 0, + 7, + -2, + -2, + 0, + 0, + 6, + 7, + 0, + -2, + 10, + 10, + -2, + 0, + 10, + 10, + -2, + 8, + -2, + 5, + 2, + 2, + -2, + -2, + -2, + 5, + 9, + 7, + 0, + 2, + 5, + 1, + 5, + 10, + -2, + 0, + 9, + 0, + -2, + 10, + 0, + 6, + 1, + -2, + 0, + -2, + 10, + 7, + 5, + -2, + -2, + -2, + -2, + 6, + 8, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + 7, + 6, + 5, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + 10, + -2, + 1, + 1, + -2, + -2, + -2, + 2, + 7, + -2, + 7, + -2, + 0, + -2, + 7, + 1, + -2, + 0, + 1, + 0, + -2, + -2, + -2, + -2, + 8, + -2, + -2, + -2, + 0, + 7, + 7, + 7, + 9, + -2, + 7, + -2, + -2, + 8, + 0, + 0, + -2, + -2, + 0, + -2, + -2, + 7, + -2, + -2, + 10, + 7, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + 8, + -2, + -2, + -2, + -2, + -2, + 8, + 1, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + 2, + -2, + -2, + -2, + 2, + -2, + 0, + -2, + 5, + -2, + -2, + -2, + -2, + 7, + 6, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + 7, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + 10, + -2, + -2, + 7, + -2, + 0, + -2, + -2, + 10, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.96875, + -0.78125, + -0.1875, + -0.9453125, + 0.0, + 0.0, + -0.609375, + -0.25, + -0.9921875, + 0.375, + -0.8046875, + -0.15625, + -0.84375, + 0.15625, + 0.0, + 0.2421875, + 0.0, + -0.8125, + 0.0, + 0.0, + 0.0, + -0.25, + -0.6171875, + -0.25, + -0.9921875, + -0.9921875, + -0.125, + -0.96875, + 0.0, + 0.25, + 0.0, + 0.0, + 0.0, + -0.7421875, + 0.0, + 0.0, + -0.9375, + -0.875, + -0.5625, + 0.0, + 0.0, + -0.90625, + -0.78125, + -0.875, + 0.0, + -0.71875, + 0.84375, + -0.859375, + -0.25, + -0.984375, + -0.59375, + -0.90625, + 0.0, + -0.9296875, + 0.0, + 0.0, + -0.96875, + 0.0, + -0.59375, + 0.0, + -0.9921875, + -0.5, + -0.40625, + -0.59375, + 0.0, + -0.9375, + -0.40625, + -0.9609375, + -0.90625, + -0.9375, + 0.5, + -0.75, + -0.75, + -0.625, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + -0.7578125, + -0.9375, + -0.78125, + 0.875, + 0.8125, + 0.0, + 0.0, + 0.0, + -0.8984375, + -0.25, + -0.984375, + -0.953125, + -0.5, + 0.625, + 0.0, + -0.9609375, + -0.5, + -0.9453125, + -0.25, + -0.9375, + -0.25, + 0.0, + 0.0, + -0.9453125, + 0.0, + -0.6953125, + -0.1953125, + 0.5, + -0.7890625, + 0.875, + 0.0, + 0.7890625, + -0.8671875, + 0.0, + 0.0, + -0.421875, + -0.2890625, + -0.984375, + 0.0859375, + -0.4609375, + 0.0, + -0.5, + -0.625, + 0.0, + -0.59375, + 0.21875, + -0.84375, + 0.0, + -0.5, + 0.0, + -0.5, + -0.59375, + -0.90625, + 0.0, + 0.0, + 0.0, + -0.125, + -0.25, + -0.921875, + -0.4140625, + -0.9375, + -0.5, + 0.90625, + -0.125, + -0.875, + 0.0, + -0.4609375, + -0.5, + -0.4296875, + 0.0, + 0.5625, + -0.2890625, + -0.6484375, + -0.59375, + 0.0, + -0.28125, + 0.0, + -0.21875, + -0.8359375, + 0.875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9921875, + -0.75, + 0.0, + 0.0, + 0.0, + -0.84375, + 0.0, + 0.0, + 0.0, + -0.65625, + -0.9140625, + 0.625, + 0.0, + 0.0, + 0.0, + 0.125, + 0.0, + 0.0, + 0.0, + 0.0625, + 0.0, + 0.875, + 0.625, + 0.0, + 0.0, + 0.0, + -0.71875, + -0.9765625, + 0.0, + -0.921875, + 0.0, + -0.9453125, + 0.0, + -0.96875, + 0.84375, + 0.0, + -0.25, + 0.84375, + 0.78125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.5, + 0.0, + 0.0, + 0.0, + 0.203125, + -0.0390625, + -0.8984375, + -0.2265625, + 0.5, + 0.0, + -0.6171875, + 0.0, + 0.0, + -0.625, + -0.9140625, + 0.3984375, + 0.0, + 0.0, + 0.1640625, + 0.0, + 0.0, + -0.5, + 0.0, + 0.0, + -0.15625, + -0.4453125, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + -0.25, + 0.0, + 0.0, + 0.0, + -0.25, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.34375, + 0.0, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.125, + 0.0, + 0.0, + -0.90625, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.8046875, + 0.0, + -0.375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.6640625, + -0.8828125, + 0.0, + -0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.296875, + -0.3984375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0546875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9765625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.46875, + 0.0, + 0.0, + -0.90625, + -0.359375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 704976.75, + 60948.3438, + 376287.875, + 21988.375, + 29058.0254, + 244516.625, + 4361.9375, + 2539.85059, + 12735.9375, + 321.458008, + 23448.207, + 46705.0, + 122825.523, + 3014.32812, + -0.0, + 1571.04199, + 168.249023, + 4425.625, + 5219.83398, + -0.718080699, + -0.0, + 27347.1777, + 1513.04297, + 28749.8359, + 14862.0, + 35918.8281, + 35200.9766, + 10590.167, + 0.696619809, + 382.220947, + 0.157973051, + 0.370715231, + -0.0, + 4024.0, + -0.0, + -0.342529774, + 1396.98047, + 2229.26025, + 2370.76172, + -0.0, + 0.637506962, + 7822.79688, + 7910.87354, + 16292.7305, + -0.703985333, + 25527.6328, + 6785.87305, + 14012.7734, + 9505.46289, + 808.644531, + 431.998047, + 185.716797, + -0.0, + 393.784973, + 1860.8125, + -0.0, + 1047.32812, + -0.428657264, + 2553.70386, + -0.0, + 794.017578, + 1244.56787, + 5947.875, + 3424.40088, + -0.508636117, + 7401.75977, + 1509.03125, + 7509.31348, + 15563.0781, + 5882.99219, + 851.740234, + 1550.28906, + 12626.1289, + 3831.14893, + 2415.28418, + -0.679205, + -0.0, + 0.577444851, + -0.0, + -0.308402807, + -0.0, + 0.19060272, + -0.0, + -0.0, + 0.695730388, + 2421.51099, + 383.529297, + 447.029877, + 1705.47095, + 591.265625, + 585.947266, + -0.243288308, + -0.0, + -0.555065393, + 360.549347, + 2049.94971, + 1415.1748, + 2894.22632, + 2538.37402, + 223.609375, + -0.0, + 1222.50977, + 4579.86182, + 6764.41406, + 3752.88696, + 1976.49585, + 1303.23804, + -0.448684603, + -0.0, + 12415.0, + -0.66432339, + 2550.55322, + 1218.3584, + 1274.23828, + 1220.49805, + 3267.99219, + -0.523092151, + 1335.93506, + 1230.77368, + -0.0, + 0.486020356, + 1654.01404, + 1632.95239, + 182.882599, + 1578.6875, + 101.873047, + -0.0, + 2513.48535, + 934.15155, + -0.116370231, + 139.974014, + 743.22168, + 2527.03833, + -0.0, + 839.317383, + -0.305437744, + 1441.42114, + 207.373047, + 330.800537, + -0.65793997, + -0.0, + -0.0, + 257.616211, + 1403.55713, + 686.105469, + 490.165222, + 1862.65625, + 2000.24463, + 1243.6665, + 429.017517, + 648.97583, + -0.375394464, + 160.239426, + 821.320312, + 1039.5343, + -0.135595873, + 646.076172, + 720.107422, + 538.205872, + 775.969727, + -0.0, + 390.18396, + -0.0, + 724.235229, + 543.69751, + 225.632858, + -0.456684738, + 0.470691144, + -0.0, + -0.304946512, + 2860.94336, + 281.800293, + -0.0, + 0.18340005, + -0.0, + 743.604492, + -0.0, + -0.0, + 0.627176881, + 1279.65137, + 409.27417, + 911.547791, + 0.43041876, + 0.224872038, + -0.0, + 567.781494, + -0.0, + -0.0, + -0.407820582, + 461.845215, + -0.0, + 130.679916, + 455.384766, + -0.471461892, + -0.0, + 0.0414263904, + 167.01825, + 175.504883, + -0.0, + 374.571075, + -0.221558735, + 120.613281, + -0.0, + 151.867157, + 677.116882, + 0.626004159, + 718.433105, + 171.310669, + 607.003174, + -0.0, + -0.615971684, + -0.187255219, + -0.0, + 369.199707, + -0.0, + -0.0, + -0.139574274, + 2254.53711, + 976.898438, + 630.280518, + 1629.21423, + 550.904785, + -0.0, + 779.791748, + -0.532523572, + -0.293539792, + 269.950684, + 544.543945, + 1828.05481, + -0.0, + -0.337529242, + 1293.36621, + -0.0, + -0.0, + 250.148926, + 0.209094957, + -0.0, + 1443.05029, + 652.215759, + 0.400463998, + -0.0, + 208.302734, + -0.0, + 0.626791358, + -0.0, + -0.0, + 368.374634, + -0.342273146, + -0.0, + -0.0, + 714.735596, + 0.532219529, + -0.0, + -0.0, + 0.122613184, + -0.0, + 563.883301, + 141.826019, + -0.0, + -0.0, + -0.591330469, + 575.480225, + -0.0, + -0.0, + 0.380495936, + -0.0, + 204.650635, + 0.324681252, + -0.0, + 376.19043, + -0.0, + -0.0, + -0.163619265, + 323.916992, + -0.0, + 276.158691, + -0.0, + 779.447266, + -0.0, + -0.588098526, + -0.0, + -0.0, + 494.029175, + 150.244141, + -0.0, + 249.465332, + -0.0, + -0.264587522, + -0.0, + 0.236463919, + -0.0, + -0.0, + 0.365317106, + 970.288269, + 160.723145, + -0.0, + 0.62778455, + -0.495709628, + -0.0, + 394.472412, + -0.0, + -0.323686808, + -0.0, + -0.500015676, + -0.0, + 0.341435254, + -0.0, + 215.581543, + -0.0, + 0.571588635, + -0.0, + -0.0, + -0.243729949, + -0.0, + 325.733276, + -0.195823565, + -0.0, + 340.361328, + -0.0, + 305.557617, + -0.0, + -0.0, + 214.410645, + 280.012695, + -0.0, + 0.216587082, + -0.0, + -0.405602366, + -0.0, + 0.450550109, + -0.0, + -0.0, + -0.402954668, + 0.403150976, + -0.0, + 0.534238577, + -0.0, + -0.0, + 0.243456319, + 0.165795937, + -0.0, + -0.0, + 0.366398722, + -0.0, + 0.460273743, + 0.307662487, + -0.0, + -0.429840118, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + -1, + 29, + 31, + 33, + 35, + -1, + -1, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + -1, + 51, + -1, + -1, + -1, + 53, + -1, + -1, + 55, + 57, + 59, + -1, + -1, + 61, + 63, + 65, + -1, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + -1, + 81, + 83, + -1, + 85, + -1, + 87, + -1, + 89, + 91, + 93, + 95, + -1, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 117, + 119, + 121, + 123, + 125, + 127, + -1, + -1, + -1, + 129, + 131, + 133, + 135, + 137, + 139, + -1, + 141, + 143, + 145, + 147, + 149, + 151, + -1, + -1, + 153, + -1, + 155, + 157, + 159, + 161, + 163, + -1, + 165, + 167, + -1, + -1, + 169, + 171, + 173, + 175, + 177, + -1, + 179, + 181, + -1, + 183, + 185, + 187, + -1, + 189, + -1, + 191, + 193, + 195, + -1, + -1, + -1, + 197, + 199, + 201, + 203, + 205, + 207, + 209, + 211, + 213, + -1, + 215, + 217, + 219, + -1, + 221, + 223, + 225, + 227, + -1, + 229, + -1, + 231, + 233, + 235, + -1, + -1, + -1, + -1, + 237, + 239, + -1, + -1, + -1, + 241, + -1, + -1, + -1, + 243, + 245, + 247, + -1, + -1, + -1, + 249, + -1, + -1, + -1, + 251, + -1, + 253, + 255, + -1, + -1, + -1, + 257, + 259, + -1, + 261, + -1, + 263, + -1, + 265, + 267, + -1, + 269, + 271, + 273, + -1, + -1, + -1, + -1, + 275, + -1, + -1, + -1, + 277, + 279, + 281, + 283, + 285, + -1, + 287, + -1, + -1, + 289, + 291, + 293, + -1, + -1, + 295, + -1, + -1, + 297, + -1, + -1, + 299, + 301, + -1, + -1, + 303, + -1, + -1, + -1, + -1, + 305, + -1, + -1, + -1, + 307, + -1, + -1, + -1, + -1, + -1, + 309, + 311, + -1, + -1, + -1, + 313, + -1, + -1, + -1, + -1, + 315, + -1, + -1, + 317, + -1, + -1, + -1, + 319, + -1, + 321, + -1, + 323, + -1, + -1, + -1, + -1, + 325, + 327, + -1, + 329, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 331, + 333, + -1, + -1, + -1, + -1, + 335, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 337, + -1, + -1, + -1, + -1, + -1, + -1, + 339, + -1, + -1, + 341, + -1, + 343, + -1, + -1, + 345, + 347, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + -1, + 30, + 32, + 34, + 36, + -1, + -1, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + -1, + 52, + -1, + -1, + -1, + 54, + -1, + -1, + 56, + 58, + 60, + -1, + -1, + 62, + 64, + 66, + -1, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + -1, + 82, + 84, + -1, + 86, + -1, + 88, + -1, + 90, + 92, + 94, + 96, + -1, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 118, + 120, + 122, + 124, + 126, + 128, + -1, + -1, + -1, + 130, + 132, + 134, + 136, + 138, + 140, + -1, + 142, + 144, + 146, + 148, + 150, + 152, + -1, + -1, + 154, + -1, + 156, + 158, + 160, + 162, + 164, + -1, + 166, + 168, + -1, + -1, + 170, + 172, + 174, + 176, + 178, + -1, + 180, + 182, + -1, + 184, + 186, + 188, + -1, + 190, + -1, + 192, + 194, + 196, + -1, + -1, + -1, + 198, + 200, + 202, + 204, + 206, + 208, + 210, + 212, + 214, + -1, + 216, + 218, + 220, + -1, + 222, + 224, + 226, + 228, + -1, + 230, + -1, + 232, + 234, + 236, + -1, + -1, + -1, + -1, + 238, + 240, + -1, + -1, + -1, + 242, + -1, + -1, + -1, + 244, + 246, + 248, + -1, + -1, + -1, + 250, + -1, + -1, + -1, + 252, + -1, + 254, + 256, + -1, + -1, + -1, + 258, + 260, + -1, + 262, + -1, + 264, + -1, + 266, + 268, + -1, + 270, + 272, + 274, + -1, + -1, + -1, + -1, + 276, + -1, + -1, + -1, + 278, + 280, + 282, + 284, + 286, + -1, + 288, + -1, + -1, + 290, + 292, + 294, + -1, + -1, + 296, + -1, + -1, + 298, + -1, + -1, + 300, + 302, + -1, + -1, + 304, + -1, + -1, + -1, + -1, + 306, + -1, + -1, + -1, + 308, + -1, + -1, + -1, + -1, + -1, + 310, + 312, + -1, + -1, + -1, + 314, + -1, + -1, + -1, + -1, + 316, + -1, + -1, + 318, + -1, + -1, + -1, + 320, + -1, + 322, + -1, + 324, + -1, + -1, + -1, + -1, + 326, + 328, + -1, + 330, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 332, + 334, + -1, + -1, + -1, + -1, + 336, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 338, + -1, + -1, + -1, + -1, + -1, + -1, + 340, + -1, + -1, + 342, + -1, + 344, + -1, + -1, + 346, + 348, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 2, + 10, + 1, + 0, + 6, + 2, + 6, + 7, + 6, + 5, + 7, + 2, + 2, + 10, + 1, + 5, + 7, + 7, + 3, + 3, + 10, + 0, + 8, + 10, + 10, + 0, + -2, + 2, + 5, + 0, + 7, + -2, + -2, + 10, + -2, + 3, + -2, + -2, + 10, + -2, + 9, + 7, + 5, + 0, + -2, + 5, + -2, + 0, + 7, + 5, + 5, + 5, + 5, + 7, + 2, + 7, + 9, + 5, + 7, + 5, + 6, + 3, + -2, + -2, + -2, + 6, + 0, + 0, + 7, + 0, + -2, + 9, + 10, + -2, + -2, + -2, + -2, + 5, + 6, + 5, + 6, + 7, + 7, + 2, + 0, + 10, + -2, + -2, + 10, + 7, + 9, + 1, + -2, + -2, + 1, + 2, + 0, + 2, + 1, + -2, + -2, + 7, + -2, + 8, + 8, + -2, + -2, + 7, + 0, + 1, + -2, + 6, + 7, + 6, + 0, + -2, + 10, + -2, + -2, + -2, + -2, + 7, + 7, + 7, + 0, + 10, + -2, + 9, + 8, + 0, + 7, + 8, + 0, + 0, + -2, + 9, + -2, + -2, + -2, + -2, + -2, + 0, + 4, + -2, + -2, + -2, + 0, + -2, + -2, + 10, + 2, + -2, + -2, + 2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 5, + -2, + 10, + -2, + 6, + 6, + -2, + -2, + 6, + 10, + -2, + 10, + 0, + 10, + -2, + 7, + 7, + -2, + 0, + -2, + -2, + 10, + 5, + 5, + 5, + -2, + 7, + 7, + 10, + 2, + 0, + 2, + -2, + -2, + 6, + -2, + 10, + -2, + -2, + 8, + -2, + 7, + 7, + 2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + 10, + 6, + 7, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + 0, + -2, + 7, + 6, + -2, + -2, + -2, + 0, + 0, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + 0, + 9, + 5, + -2, + -2, + 6, + -2, + -2, + 7, + 0, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 2, + 1, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + 7, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 8, + 7, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 0, + -2, + 9, + -2, + 7, + 6, + -2, + -2, + 1, + -2, + -2, + -2, + -2, + 10, + -2, + -2, + -2, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 9, + 9, + 5, + -2, + 10, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + 2, + -2, + -2, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.96875, + -0.84375, + -0.15625, + -0.578125, + -0.8046875, + -0.28125, + -0.984375, + -0.953125, + -0.9921875, + 0.0, + -0.453125, + -0.9375, + 0.28125, + -0.875, + 0.9375, + 0.25, + -0.9140625, + -0.8203125, + 0.0, + 0.0, + -0.5, + 0.328125, + -0.625, + -0.6875, + -0.84375, + -0.96875, + 0.0, + -0.9375, + 0.0, + -0.609375, + -0.28125, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.0, + -0.25, + -0.5859375, + 0.75, + -0.0546875, + 0.0, + 0.375, + 0.0, + -0.6640625, + -0.7578125, + -0.625, + 0.25, + 0.0, + -0.875, + -0.875, + -0.59375, + -0.96875, + -0.25, + 0.25, + 0.640625, + 0.625, + -0.6640625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9765625, + 0.40625, + 0.015625, + -0.6875, + 0.8125, + 0.0, + -0.5, + -0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.5, + -0.9921875, + 0.25, + -0.8828125, + -0.9609375, + -0.890625, + -0.34375, + 0.0390625, + -0.9375, + 0.0, + 0.0, + 0.15625, + -0.9375, + -0.5, + 0.53125, + 0.0, + 0.0, + 0.96875, + -0.9375, + 0.828125, + 0.96875, + 0.71875, + 0.0, + 0.0, + -0.921875, + 0.0, + -0.75, + -0.5, + 0.0, + 0.0, + -0.9140625, + 0.8359375, + -0.59375, + 0.0, + -0.890625, + -0.78125, + -0.90625, + 0.5546875, + 0.0, + -0.71875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.953125, + -0.9609375, + -0.8125, + 0.375, + -0.65625, + 0.0, + -0.25, + -0.625, + -0.6953125, + -0.921875, + -0.75, + -0.578125, + -0.4609375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.15625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.46875, + 0.0, + 0.0, + -0.65625, + -0.71875, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.109375, + 0.0, + -0.5, + 0.0, + -0.34375, + 0.0, + -0.984375, + -0.9921875, + 0.0, + 0.0, + -0.8984375, + -0.28125, + 0.0, + -0.625, + -0.9453125, + -0.9375, + 0.0, + -0.9140625, + -0.9375, + 0.0, + -0.078125, + 0.0, + 0.0, + 0.9375, + -0.75, + 0.375, + 0.625, + 0.0, + -0.984375, + -0.96875, + -0.9375, + -0.75, + -0.984375, + -0.71875, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.28125, + 0.0, + 0.0, + -0.875, + 0.0, + -0.90625, + -0.953125, + -0.78125, + 0.0, + 0.0, + -0.625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.3828125, + 0.0, + 0.0, + -0.6875, + -0.953125, + -0.21875, + -0.1953125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9140625, + 0.0, + 0.0, + 0.0, + -0.453125, + 0.0, + -0.9375, + -0.9765625, + 0.0, + 0.0, + 0.0, + -0.4765625, + -0.3671875, + 0.0, + -0.7265625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8828125, + -0.25, + -0.75, + 0.0, + 0.0, + -0.9921875, + 0.0, + 0.0, + -0.6015625, + -0.828125, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.59375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.21875, + -0.6953125, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.625, + -0.9140625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.265625, + 0.0, + 0.0, + 0.0, + -0.9453125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.7421875, + 0.0, + -0.5, + 0.0, + -0.9140625, + -0.421875, + 0.0, + 0.0, + 0.75, + 0.0, + 0.0, + 0.0, + 0.0, + 0.59375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.578125, + 0.0, + 0.0, + -0.75, + -0.5, + 0.0, + 0.375, + -0.8984375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9609375, + 0.0, + 0.0, + 0.0, + -0.625, + 0.0, + 0.0, + 0.0, + 0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 282496.094, + 36267.4688, + 156169.062, + 14947.2969, + 12818.5146, + 85483.7422, + 41295.6875, + 2319.073, + 9502.875, + 18102.0039, + 3515.42383, + 51175.0703, + 2411.53906, + 20171.6953, + 10318.5625, + 192.180054, + 1224.69299, + 2735.79688, + 2324.86865, + 2791.22803, + 3255.32617, + 872.15863, + 794.375, + 14120.3643, + 17131.0977, + 7870.14941, + 0.592340529, + 10475.4326, + 9556.70312, + 5343.28125, + 5801.88867, + -0.238279015, + -0.0, + 468.309326, + -0.0, + 2241.125, + -0.0, + -0.161948621, + 767.104492, + -0.528290629, + 2130.52539, + 622.099609, + 464.205933, + 1014.90417, + 0.396752834, + 226.914062, + -0.0, + 5166.60938, + 5983.54395, + 7779.17432, + 7630.60938, + 555.562012, + 633.616211, + 4031.21729, + 1354.02197, + 4706.87891, + 789.416016, + 2455.60596, + 1214.6875, + 4075.56836, + 1465.22437, + 384.167236, + -0.0, + -0.0, + 0.58607018, + 741.847168, + 1712.09912, + 1054.65771, + 2600.07031, + 1079.14453, + -0.0, + 492.018036, + 190.406677, + -0.0, + -0.462764859, + 0.562245071, + -0.0, + 2174.4917, + 4699.48438, + 2692.46191, + 2264.05566, + 2336.11768, + 4011.77637, + 1314.8125, + 3961.90894, + 145.608398, + -0.0, + -0.0, + 532.478516, + 5244.86816, + 413.025085, + 777.401367, + -0.0, + -0.0, + 922.703125, + 719.302246, + 104.316406, + 1291.37305, + 161.880417, + -0.607664108, + -0.0, + 421.626953, + -0.0, + 120.455414, + 1507.54871, + -0.0, + 0.265381515, + 613.806702, + 633.939026, + 862.795166, + 0.593573451, + 507.428192, + 2980.90479, + 287.606445, + 226.970474, + 0.498253286, + 1220.27539, + 0.244596049, + -0.0, + -0.179338396, + -0.0, + 363.445251, + 567.51001, + 2631.06641, + 1988.19556, + 426.753906, + -0.0, + 627.40979, + 1533.65283, + 4408.65918, + 5137.52246, + 1493.65308, + 134.431396, + 597.476562, + -0.0, + 2186.22778, + -0.440478206, + -0.0, + -0.437818378, + 0.534407079, + -0.0, + 685.634521, + 1988.61523, + -0.0, + -0.38760671, + -0.0, + 1584.42871, + -0.534934103, + -0.0, + 728.876709, + 208.921204, + -0.177697435, + -0.0, + 1394.26465, + -0.0, + -0.0, + 0.162364483, + -0.0, + -0.450788021, + -0.0, + -0.14340581, + 0.554359138, + -0.0, + -0.0, + -0.245490789, + 124.778198, + -0.0, + 423.549561, + -0.0, + 236.886719, + -0.0, + 341.044189, + 196.380554, + -0.411565483, + -0.0, + 278.581146, + 495.201111, + 0.41034922, + 439.286072, + 198.913361, + 198.630234, + -0.0, + 489.260498, + 216.214844, + -0.0, + 385.995758, + 0.47734794, + -0.0, + 140.234863, + 461.554626, + 257.365356, + 514.114258, + -0.0, + 270.500977, + 978.732239, + 397.248688, + 945.474121, + 764.725586, + 115.937347, + -0.0, + -0.362419993, + 4351.8125, + -0.530958951, + 1339.98926, + -0.226501137, + -0.216470912, + 848.972229, + -0.0, + 1909.42969, + 2442.64282, + 393.288086, + 0.437914073, + -0.0, + 229.480301, + 0.0375155136, + -0.0, + -0.438742876, + -0.0, + 0.36332047, + -0.0, + 0.323524624, + -0.0, + 251.563965, + 0.600188553, + -0.0, + 347.55304, + 398.172668, + 686.179932, + 169.922394, + -0.314345717, + -0.0, + -0.216525733, + -0.0, + -0.0, + -0.196464211, + 124.950043, + -0.00474914629, + 0.287098944, + -0.0, + 234.61615, + 0.467102677, + 413.704773, + 559.724182, + -0.303854495, + -0.0, + -0.0, + 226.627441, + 200.019348, + -0.0, + 158.520996, + -0.0, + -0.0, + -0.431458175, + 0.489678502, + -0.0, + 925.51001, + 208.313202, + 233.083008, + -0.0, + -0.0, + 334.451172, + -0.0865372345, + -0.0, + 889.945312, + 956.116211, + 0.250348002, + -0.0, + 252.614014, + -0.0393951125, + 0.496329665, + -0.0, + -0.440185338, + 436.638855, + 238.262695, + -0.0, + -0.0, + -0.232186392, + -0.268332601, + -0.0, + -0.0, + 842.15741, + 734.555542, + -0.0, + 132.263702, + 0.220872924, + 0.241065755, + -0.0, + 0.106263235, + -0.0, + -0.0, + 0.207524598, + -0.0, + 400.184998, + 552.964233, + -0.0, + -0.0, + 0.232635319, + -0.0, + 162.509644, + -0.0, + 0.343814522, + 0.219867691, + 430.451447, + -0.0, + -0.146346644, + -0.500973761, + -0.0, + 291.705566, + -0.0, + 269.3125, + -0.0, + 433.181946, + 537.160645, + -0.0, + 0.404118598, + 309.685608, + -0.0, + -0.0, + -0.488286972, + -0.0, + 210.27063, + -0.407638609, + -0.0, + -0.214008719, + -0.0, + 187.456543, + -0.0, + -0.0, + -0.488048971, + -0.277351737, + -0.0, + 293.044159, + 0.0337233804, + 193.163696, + 216.581543, + 1006.37354, + -0.480245739, + 176.920441, + 293.592499, + -0.221826121, + -0.0, + -0.0, + 0.251315951, + 0.481508315, + -0.0, + 0.182792872, + -0.0, + -0.265325963, + -0.0, + 249.826294, + -0.0, + -0.0, + 0.397380114, + 279.862305, + -0.0, + -0.161628962, + -0.0, + 130.231079, + -0.0, + -0.0, + 0.17591098, + -0.34571445, + -0.0, + 0.274183989, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + -1, + 53, + 55, + 57, + 59, + -1, + -1, + 61, + -1, + 63, + -1, + -1, + 65, + -1, + 67, + 69, + 71, + 73, + -1, + 75, + -1, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + -1, + -1, + -1, + 107, + 109, + 111, + 113, + 115, + -1, + 117, + 119, + -1, + -1, + -1, + -1, + 121, + 123, + 125, + 127, + 129, + 131, + 133, + 135, + 137, + -1, + -1, + 139, + 141, + 143, + 145, + -1, + -1, + 147, + 149, + 151, + 153, + 155, + -1, + -1, + 157, + -1, + 159, + 161, + -1, + -1, + 163, + 165, + 167, + -1, + 169, + 171, + 173, + 175, + -1, + 177, + -1, + -1, + -1, + -1, + 179, + 181, + 183, + 185, + 187, + -1, + 189, + 191, + 193, + 195, + 197, + 199, + 201, + -1, + 203, + -1, + -1, + -1, + -1, + -1, + 205, + 207, + -1, + -1, + -1, + 209, + -1, + -1, + 211, + 213, + -1, + -1, + 215, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 217, + -1, + 219, + -1, + 221, + -1, + 223, + 225, + -1, + -1, + 227, + 229, + -1, + 231, + 233, + 235, + -1, + 237, + 239, + -1, + 241, + -1, + -1, + 243, + 245, + 247, + 249, + -1, + 251, + 253, + 255, + 257, + 259, + 261, + -1, + -1, + 263, + -1, + 265, + -1, + -1, + 267, + -1, + 269, + 271, + 273, + -1, + -1, + 275, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 277, + -1, + -1, + 279, + 281, + 283, + 285, + -1, + -1, + -1, + -1, + -1, + -1, + 287, + -1, + -1, + -1, + 289, + -1, + 291, + 293, + -1, + -1, + -1, + 295, + 297, + -1, + 299, + -1, + -1, + -1, + -1, + -1, + 301, + 303, + 305, + -1, + -1, + 307, + -1, + -1, + 309, + 311, + -1, + -1, + 313, + -1, + -1, + -1, + -1, + 315, + 317, + -1, + -1, + -1, + -1, + -1, + -1, + 319, + 321, + -1, + 323, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 325, + 327, + -1, + -1, + -1, + -1, + 329, + -1, + -1, + -1, + 331, + -1, + -1, + -1, + -1, + 333, + -1, + 335, + -1, + 337, + 339, + -1, + -1, + 341, + -1, + -1, + -1, + -1, + 343, + -1, + -1, + -1, + -1, + 345, + -1, + -1, + -1, + -1, + -1, + 347, + -1, + 349, + 351, + 353, + -1, + 355, + 357, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 359, + -1, + -1, + -1, + 361, + -1, + -1, + -1, + 363, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + -1, + 54, + 56, + 58, + 60, + -1, + -1, + 62, + -1, + 64, + -1, + -1, + 66, + -1, + 68, + 70, + 72, + 74, + -1, + 76, + -1, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + -1, + -1, + -1, + 108, + 110, + 112, + 114, + 116, + -1, + 118, + 120, + -1, + -1, + -1, + -1, + 122, + 124, + 126, + 128, + 130, + 132, + 134, + 136, + 138, + -1, + -1, + 140, + 142, + 144, + 146, + -1, + -1, + 148, + 150, + 152, + 154, + 156, + -1, + -1, + 158, + -1, + 160, + 162, + -1, + -1, + 164, + 166, + 168, + -1, + 170, + 172, + 174, + 176, + -1, + 178, + -1, + -1, + -1, + -1, + 180, + 182, + 184, + 186, + 188, + -1, + 190, + 192, + 194, + 196, + 198, + 200, + 202, + -1, + 204, + -1, + -1, + -1, + -1, + -1, + 206, + 208, + -1, + -1, + -1, + 210, + -1, + -1, + 212, + 214, + -1, + -1, + 216, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 218, + -1, + 220, + -1, + 222, + -1, + 224, + 226, + -1, + -1, + 228, + 230, + -1, + 232, + 234, + 236, + -1, + 238, + 240, + -1, + 242, + -1, + -1, + 244, + 246, + 248, + 250, + -1, + 252, + 254, + 256, + 258, + 260, + 262, + -1, + -1, + 264, + -1, + 266, + -1, + -1, + 268, + -1, + 270, + 272, + 274, + -1, + -1, + 276, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 278, + -1, + -1, + 280, + 282, + 284, + 286, + -1, + -1, + -1, + -1, + -1, + -1, + 288, + -1, + -1, + -1, + 290, + -1, + 292, + 294, + -1, + -1, + -1, + 296, + 298, + -1, + 300, + -1, + -1, + -1, + -1, + -1, + 302, + 304, + 306, + -1, + -1, + 308, + -1, + -1, + 310, + 312, + -1, + -1, + 314, + -1, + -1, + -1, + -1, + 316, + 318, + -1, + -1, + -1, + -1, + -1, + -1, + 320, + 322, + -1, + 324, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 326, + 328, + -1, + -1, + -1, + -1, + 330, + -1, + -1, + -1, + 332, + -1, + -1, + -1, + -1, + 334, + -1, + 336, + -1, + 338, + 340, + -1, + -1, + 342, + -1, + -1, + -1, + -1, + 344, + -1, + -1, + -1, + -1, + 346, + -1, + -1, + -1, + -1, + -1, + 348, + -1, + 350, + 352, + 354, + -1, + 356, + 358, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 360, + -1, + -1, + -1, + 362, + -1, + -1, + -1, + 364, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 2, + 10, + 2, + 7, + 6, + 8, + 0, + 0, + 6, + 5, + 8, + 2, + 1, + 2, + -2, + 1, + -2, + 7, + 6, + 8, + 10, + 7, + 0, + 5, + 1, + 5, + 1, + 0, + -2, + -2, + 10, + 0, + 5, + 5, + 1, + 7, + 0, + 7, + 6, + -2, + -2, + 0, + 7, + 6, + 9, + 5, + 7, + 8, + 9, + 2, + 2, + -2, + 10, + -2, + -2, + -2, + -2, + 0, + 9, + 7, + 5, + 0, + 5, + -2, + 3, + 0, + -2, + 6, + -2, + 9, + 6, + -2, + 5, + -2, + -2, + 10, + 7, + 7, + 7, + 10, + 10, + 2, + 6, + 6, + 0, + 2, + 2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + 10, + -2, + -2, + 0, + -2, + 10, + -2, + 0, + -2, + 7, + -2, + 7, + 7, + 0, + 6, + 5, + 4, + 10, + 6, + 7, + 6, + 7, + 2, + 2, + 1, + 0, + -2, + 2, + -2, + -2, + 7, + 3, + -2, + -2, + 2, + -2, + 0, + -2, + -2, + -2, + -2, + 7, + 6, + -2, + 10, + -2, + -2, + -2, + 7, + -2, + -2, + 9, + 7, + 9, + -2, + 7, + -2, + -2, + -2, + 0, + -2, + 0, + 0, + 0, + -2, + 5, + 5, + 0, + 9, + 7, + 6, + 0, + 5, + 6, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + 0, + 0, + -2, + -2, + 6, + -2, + 0, + -2, + 7, + 7, + -2, + 0, + -2, + -2, + 0, + -2, + 0, + -2, + 0, + 6, + -2, + 6, + -2, + 7, + -2, + 1, + 0, + -2, + -2, + 5, + 6, + 0, + -2, + -2, + 2, + 9, + 7, + -2, + -2, + -2, + -2, + 3, + -2, + 4, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + 10, + -2, + -2, + -2, + 6, + 6, + -2, + -2, + 6, + 10, + 10, + 5, + 10, + -2, + -2, + -2, + -2, + -2, + 9, + -2, + 8, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + 5, + 6, + -2, + 0, + -2, + 6, + 5, + 9, + -2, + -2, + -2, + 4, + -2, + -2, + -2, + 0, + 5, + -2, + -2, + -2, + -2, + -2, + 10, + -2, + 0, + -2, + -2, + -2, + 7, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 8, + 7, + -2, + 5, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + 5, + -2, + -2, + -2, + -2, + 0, + 0, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 10, + 10, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.96875, + -0.84375, + -0.03125, + -0.9375, + -0.84375, + -0.75, + -0.6953125, + 0.390625, + -0.984375, + 0.125, + -0.75, + -0.9375, + -0.59375, + 0.40625, + 0.0, + -0.59375, + 0.0, + -0.890625, + -0.96875, + -0.75, + -0.5, + -0.6640625, + 0.3515625, + -0.75, + 0.21875, + 0.125, + 0.9375, + -0.953125, + 0.0, + 0.0, + -0.90625, + -0.6875, + -0.5, + -0.125, + -0.59375, + -0.875, + 0.3515625, + -0.7421875, + -0.984375, + 0.0, + 0.0, + -0.2109375, + 0.5234375, + -0.9296875, + -0.25, + -0.625, + -0.90625, + -0.625, + -0.25, + -0.15625, + -0.9375, + 0.0, + -0.1875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.3671875, + 0.0, + -0.90625, + 0.875, + -0.421875, + 0.5, + 0.0, + 0.0, + -0.296875, + 0.0, + -0.9375, + 0.0, + 0.0, + -0.90625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.90625, + -0.25, + -0.953125, + -0.9140625, + -0.90625, + -0.59375, + -0.6875, + -0.625, + -0.90625, + -0.78125, + -0.75, + -0.9375, + 0.0, + 0.0, + 0.21875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.171875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0390625, + 0.0, + 0.0, + -0.5, + 0.0, + 0.0, + -0.6328125, + 0.0, + 0.125, + 0.0, + -0.5390625, + 0.0, + -0.109375, + 0.0, + -0.9375, + -0.25, + -0.3671875, + -0.765625, + 0.375, + 0.0, + -0.84375, + -0.8984375, + -0.953125, + -0.953125, + -0.9296875, + -0.53125, + -0.90625, + 0.78125, + -0.828125, + 0.0, + -0.65625, + 0.0, + 0.0, + -0.15625, + 0.0, + 0.0, + 0.0, + -0.59375, + 0.0, + 0.90625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + -0.9375, + 0.0, + -0.8125, + 0.0, + 0.0, + 0.0, + -0.65625, + 0.0, + 0.0, + 0.25, + -0.9140625, + -0.5, + 0.0, + -0.859375, + 0.0, + 0.0, + 0.0, + -0.90625, + 0.0, + -0.1875, + 0.953125, + -0.671875, + 0.0, + 0.375, + 0.625, + -0.6953125, + 0.0, + -0.984375, + -0.796875, + -0.984375, + 0.25, + -0.859375, + 0.0, + -0.9921875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.984375, + 0.0, + 0.0, + 0.0, + -0.4921875, + -0.3828125, + 0.0, + 0.0, + -0.46875, + 0.0, + -0.015625, + 0.0, + -0.4296875, + -0.359375, + 0.0, + -0.3984375, + 0.0, + 0.0, + -0.7734375, + 0.0, + -0.8359375, + 0.0, + 0.125, + -0.9375, + 0.0, + -0.7578125, + 0.0, + -0.96875, + 0.0, + 0.71875, + 0.4453125, + 0.0, + 0.0, + 0.625, + -0.9375, + 0.7421875, + 0.0, + 0.0, + -0.40625, + -0.5, + -0.90625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.125, + 0.0, + 0.5, + 0.0, + 0.0, + 0.0, + -0.8984375, + -0.9765625, + 0.0, + 0.0, + -0.984375, + -0.21875, + -0.40625, + -0.625, + 0.53125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.328125, + -0.625, + -0.9921875, + 0.0, + 0.5625, + 0.0, + -0.953125, + 0.75, + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9140625, + -0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8125, + 0.0, + 0.625, + 0.0, + 0.0, + 0.0, + -0.5, + 0.0, + -0.3203125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + -0.90625, + 0.0, + 0.875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.3671875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.4921875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.421875, + 0.75, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9140625, + -0.265625, + 0.0, + -0.8828125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.65625, + -0.34375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 114453.422, + 19522.4922, + 69436.5547, + 14843.125, + 6742.64648, + 57752.4375, + 1646.96875, + 1510.27173, + 7516.36719, + 6755.04688, + 2976.16406, + 26073.6699, + 16400.3984, + 572.316406, + -0.0, + 2510.09033, + 0.346479148, + 8002.46094, + 918.210144, + 1963.89832, + 1502.77002, + 815.119141, + 4216.76514, + 7819.98584, + 12953.3477, + 5372.02246, + 4784.72656, + 2898.40283, + 0.534402788, + -0.0, + 276.855469, + 2824.38281, + 4064.31885, + 648.845398, + 927.710693, + 1205.50562, + 205.450195, + 631.299316, + 136.784332, + -0.0, + 0.459758431, + 822.742126, + 356.835938, + 4924.17773, + 3700.4209, + 7910.271, + 3880.22656, + 2495.47363, + 1259.53088, + 555.46875, + 1209.88623, + -0.177903712, + 316.501953, + -0.515984356, + -0.0, + -0.0, + 0.531067491, + 1597.60278, + 833.387085, + 252.125671, + 258.579712, + 851.175537, + 827.338501, + -0.239730224, + 702.579834, + 334.624756, + -0.0, + 960.862305, + -0.0, + 584.013184, + 267.346893, + -0.0, + 765.777222, + 0.536687732, + -0.0, + 7845.02588, + 476.457275, + 2164.93945, + 2643.3916, + 4026.33496, + 2379.08008, + 1720.36816, + 1946.99219, + 1783.53662, + 534.316406, + 918.048096, + 659.591309, + -0.556452513, + -0.0, + 1077.96265, + -0.45217976, + 0.401497066, + -0.0, + -0.933596671, + -0.0, + 435.034058, + -0.0, + -0.327872097, + -0.0, + 0.177693814, + -0.0, + -0.0, + 0.368826687, + 298.349091, + -0.257303447, + -0.2677674, + 792.662292, + -0.0, + -0.581362486, + 146.867676, + -0.0, + 190.328613, + -0.0, + 172.857483, + -0.0, + 1063.85181, + -0.0, + 2279.99146, + 664.759766, + 1240.0802, + 318.073975, + 134.415726, + 1588.125, + 1501.67969, + 863.515381, + 1638.94421, + 5406.42773, + 1353.38428, + 596.319214, + 961.89502, + 853.963806, + 120.804688, + -0.0, + 1149.54004, + -0.0, + -0.0, + 384.350586, + 928.422913, + 0.31048876, + -0.0, + 211.103394, + 0.000828896998, + 510.078125, + -0.0, + 0.340287983, + -0.0, + 0.248442054, + 558.599915, + 269.627686, + -0.0, + 240.400879, + 0.275793582, + -0.0, + -0.0, + 184.47934, + -0.704537868, + -0.0, + 125.851013, + 2275.08765, + 875.197266, + -0.0, + 432.365967, + -0.0, + -0.0, + 0.559853256, + 219.437119, + -0.0, + 175.32016, + 623.386719, + 776.587646, + -0.0, + 1292.22266, + 160.287262, + 1939.61743, + 389.041443, + 716.886719, + 511.179382, + 798.889648, + 288.829956, + 176.781494, + -0.0, + 630.847778, + -0.334572315, + -0.0, + 0.416598439, + -0.0, + -0.522681117, + 425.13623, + -0.0, + -0.490985662, + -0.0, + 710.241699, + 137.203949, + -0.331604689, + -0.0, + 478.589355, + -0.0, + 1244.60352, + -0.0, + 1077.50049, + 298.34671, + -0.0, + 103.269531, + -0.22282064, + -0.0, + 251.473724, + -0.0, + 615.699219, + -0.0287370253, + 396.133331, + 273.724609, + -0.0, + 412.127563, + -0.0, + 222.513489, + 0.110550798, + 124.261444, + 1476.7207, + -0.0, + -0.0, + 283.853516, + 250.04126, + 512.355408, + 0.122484252, + -0.0, + 353.538574, + 312.096313, + 388.871338, + -0.0289016832, + -0.0, + -0.334191799, + -0.00705790985, + 158.082825, + -0.0, + 233.988281, + -0.124189988, + -0.0, + -0.141967043, + -0.0, + -0.0, + 137.122864, + -0.0, + 123.166016, + -0.0, + -0.300338715, + -0.0, + 213.967163, + 384.216553, + -0.0, + -0.0, + 477.058594, + 784.401245, + 221.782684, + 157.227905, + 111.253899, + -0.0, + 0.480383247, + -0.0, + -0.164454997, + -0.0, + 413.795898, + -0.119818389, + 113.318115, + -0.347015858, + -0.0, + 0.331558675, + -0.0, + -0.0, + -0.258310199, + -0.0, + -0.139901251, + 1374.25, + 911.847656, + 211.015625, + -0.0, + 175.340332, + -0.0, + 296.337677, + 142.524841, + 136.947021, + -0.0, + -0.0, + 0.285261065, + 190.298462, + -0.0, + 0.38884747, + -0.0, + 1104.18945, + 215.68335, + -0.286154002, + -0.0, + -0.357244134, + -0.0, + -0.0, + 218.736328, + -0.0, + 165.753662, + 0.499968529, + -0.0, + -0.0, + 181.321533, + -0.0, + 122.776871, + 0.216920987, + -0.0, + -0.0, + -0.151644856, + 0.317670494, + -0.0, + 0.223356649, + -0.0, + 1343.47754, + 105.75959, + -0.0, + 109.433594, + 0.440999866, + -0.0, + -0.326773554, + -0.0, + 111.485962, + -0.0, + -0.252613097, + -0.0, + -0.251724243, + -0.0, + -0.0, + 189.573242, + -0.0, + 0.393410027, + -0.0, + 0.121542916, + -0.0, + 0.298900366, + 526.668396, + 284.925537, + -0.335305154, + -0.0, + -0.0, + 0.159726441, + 399.376953, + 721.763184, + 0.00566894328, + 1576.56543, + 0.613021374, + -0.0, + -0.0, + 0.200779721, + 0.140078411, + -0.0, + -0.212018967, + 0.10100057, + -0.388346583, + -0.0, + -0.0, + 248.982422, + 101.791382, + -0.0, + -0.562191725, + -0.0, + 0.30739972, + -0.0, + 0.194088191, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + -1, + 29, + -1, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + -1, + -1, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + -1, + -1, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + -1, + 91, + -1, + -1, + -1, + -1, + 93, + 95, + 97, + 99, + 101, + 103, + -1, + 105, + 107, + -1, + 109, + -1, + 111, + 113, + -1, + 115, + -1, + -1, + 117, + 119, + 121, + 123, + 125, + 127, + 129, + 131, + 133, + 135, + 137, + 139, + -1, + -1, + 141, + -1, + -1, + -1, + -1, + -1, + 143, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 145, + -1, + -1, + 147, + -1, + -1, + 149, + -1, + 151, + -1, + 153, + -1, + 155, + -1, + 157, + 159, + 161, + 163, + 165, + 167, + 169, + 171, + 173, + 175, + 177, + 179, + 181, + 183, + 185, + -1, + 187, + -1, + -1, + 189, + 191, + -1, + -1, + 193, + -1, + 195, + -1, + -1, + -1, + -1, + 197, + 199, + -1, + 201, + -1, + -1, + -1, + 203, + -1, + -1, + 205, + 207, + 209, + -1, + 211, + -1, + -1, + -1, + 213, + -1, + 215, + 217, + 219, + -1, + 221, + 223, + 225, + 227, + 229, + 231, + 233, + 235, + 237, + -1, + 239, + -1, + -1, + -1, + -1, + -1, + 241, + -1, + -1, + -1, + 243, + 245, + -1, + -1, + 247, + -1, + 249, + -1, + 251, + 253, + -1, + 255, + -1, + -1, + 257, + -1, + 259, + -1, + 261, + 263, + -1, + 265, + -1, + 267, + -1, + 269, + 271, + -1, + -1, + 273, + 275, + 277, + -1, + -1, + 279, + 281, + 283, + -1, + -1, + -1, + -1, + 285, + -1, + 287, + -1, + -1, + -1, + -1, + -1, + 289, + -1, + 291, + -1, + -1, + -1, + 293, + 295, + -1, + -1, + 297, + 299, + 301, + 303, + 305, + -1, + -1, + -1, + -1, + -1, + 307, + -1, + 309, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 311, + 313, + 315, + -1, + 317, + -1, + 319, + 321, + 323, + -1, + -1, + -1, + 325, + -1, + -1, + -1, + 327, + 329, + -1, + -1, + -1, + -1, + -1, + 331, + -1, + 333, + -1, + -1, + -1, + 335, + -1, + 337, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 339, + 341, + -1, + 343, + -1, + -1, + -1, + -1, + 345, + -1, + -1, + -1, + -1, + -1, + -1, + 347, + -1, + -1, + -1, + -1, + -1, + -1, + 349, + 351, + -1, + -1, + -1, + -1, + 353, + 355, + -1, + 357, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 359, + 361, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + -1, + 30, + -1, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + -1, + -1, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + -1, + -1, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + -1, + 92, + -1, + -1, + -1, + -1, + 94, + 96, + 98, + 100, + 102, + 104, + -1, + 106, + 108, + -1, + 110, + -1, + 112, + 114, + -1, + 116, + -1, + -1, + 118, + 120, + 122, + 124, + 126, + 128, + 130, + 132, + 134, + 136, + 138, + 140, + -1, + -1, + 142, + -1, + -1, + -1, + -1, + -1, + 144, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 146, + -1, + -1, + 148, + -1, + -1, + 150, + -1, + 152, + -1, + 154, + -1, + 156, + -1, + 158, + 160, + 162, + 164, + 166, + 168, + 170, + 172, + 174, + 176, + 178, + 180, + 182, + 184, + 186, + -1, + 188, + -1, + -1, + 190, + 192, + -1, + -1, + 194, + -1, + 196, + -1, + -1, + -1, + -1, + 198, + 200, + -1, + 202, + -1, + -1, + -1, + 204, + -1, + -1, + 206, + 208, + 210, + -1, + 212, + -1, + -1, + -1, + 214, + -1, + 216, + 218, + 220, + -1, + 222, + 224, + 226, + 228, + 230, + 232, + 234, + 236, + 238, + -1, + 240, + -1, + -1, + -1, + -1, + -1, + 242, + -1, + -1, + -1, + 244, + 246, + -1, + -1, + 248, + -1, + 250, + -1, + 252, + 254, + -1, + 256, + -1, + -1, + 258, + -1, + 260, + -1, + 262, + 264, + -1, + 266, + -1, + 268, + -1, + 270, + 272, + -1, + -1, + 274, + 276, + 278, + -1, + -1, + 280, + 282, + 284, + -1, + -1, + -1, + -1, + 286, + -1, + 288, + -1, + -1, + -1, + -1, + -1, + 290, + -1, + 292, + -1, + -1, + -1, + 294, + 296, + -1, + -1, + 298, + 300, + 302, + 304, + 306, + -1, + -1, + -1, + -1, + -1, + 308, + -1, + 310, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 312, + 314, + 316, + -1, + 318, + -1, + 320, + 322, + 324, + -1, + -1, + -1, + 326, + -1, + -1, + -1, + 328, + 330, + -1, + -1, + -1, + -1, + -1, + 332, + -1, + 334, + -1, + -1, + -1, + 336, + -1, + 338, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 340, + 342, + -1, + 344, + -1, + -1, + -1, + -1, + 346, + -1, + -1, + -1, + -1, + -1, + -1, + 348, + -1, + -1, + -1, + -1, + -1, + -1, + 350, + 352, + -1, + -1, + -1, + -1, + 354, + 356, + -1, + 358, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 360, + 362, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 8, + 2, + 5, + 10, + 2, + 3, + 2, + 0, + 6, + 4, + 0, + 7, + 7, + 3, + 9, + 7, + 6, + 5, + 7, + 2, + 2, + 2, + 7, + -2, + -2, + 6, + -2, + 0, + 2, + -2, + -2, + -2, + 7, + 7, + 6, + 1, + 9, + -2, + 5, + 10, + 0, + 9, + 0, + 5, + -2, + 10, + 6, + -2, + 0, + -2, + -2, + 0, + 2, + 3, + -2, + 7, + -2, + 5, + 5, + 0, + 1, + 6, + 0, + -2, + -2, + 8, + 6, + 6, + 7, + 0, + 6, + 7, + 5, + 2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 0, + 0, + 4, + 0, + -2, + 0, + -2, + 7, + 9, + 6, + 6, + 10, + 9, + 10, + 1, + 5, + 5, + 0, + -2, + 5, + -2, + -2, + -2, + 6, + 7, + 7, + 10, + 0, + 9, + 7, + 7, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + 7, + 0, + -2, + 7, + 0, + -2, + -2, + -2, + -2, + 1, + 7, + 0, + -2, + -2, + 7, + 10, + -2, + 0, + 6, + -2, + 0, + 0, + 5, + 7, + -2, + 0, + 7, + 10, + 6, + -2, + 6, + -2, + 6, + -2, + -2, + 10, + -2, + -2, + -2, + 0, + -2, + 0, + -2, + -2, + 6, + -2, + 0, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + 10, + 7, + 7, + 10, + 10, + -2, + -2, + 1, + 7, + 0, + -2, + 6, + -2, + -2, + -2, + 9, + 7, + 5, + 10, + 0, + 10, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + 1, + -2, + -2, + -2, + -2, + -2, + 1, + -2, + 8, + 7, + -2, + -2, + 0, + -2, + 5, + 7, + -2, + -2, + -2, + 10, + -2, + 6, + -2, + 10, + -2, + -2, + -2, + 6, + -2, + 0, + 5, + 6, + 10, + -2, + 0, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 0, + 7, + 7, + 9, + 10, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + 10, + -2, + -2, + -2, + 6, + 7, + -2, + -2, + -2, + -2, + -2, + 10, + -2, + 0, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.625, + -0.96875, + 0.25, + -0.875, + -0.40625, + 0.0, + -0.75, + -0.34375, + -0.7734375, + 0.0, + -0.984375, + -0.9765625, + -0.1796875, + 0.0, + 0.0, + -0.953125, + -0.9921875, + -0.5, + -0.328125, + -0.71875, + -0.9375, + 0.96875, + -0.9765625, + 0.0, + 0.0, + -0.9765625, + 0.0, + -0.296875, + -0.96875, + 0.0, + 0.0, + 0.0, + -0.9140625, + -0.890625, + -0.9765625, + -0.59375, + -0.25, + 0.0, + 0.25, + -0.875, + -0.6484375, + -0.25, + -0.4609375, + 0.125, + 0.0, + -0.1875, + -0.875, + 0.0, + -0.65625, + 0.0, + 0.0, + -0.0078125, + -0.9375, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.125, + 0.5, + -0.7578125, + 0.9375, + -0.9765625, + 0.203125, + 0.0, + 0.0, + -0.875, + -0.5234375, + -0.9296875, + -0.9453125, + 0.484375, + -0.921875, + -0.953125, + 0.0, + -0.34375, + 0.0, + 0.0, + 0.0, + -0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.328125, + 0.0, + -0.921875, + 0.28125, + 0.0, + -0.0390625, + 0.0, + -0.09375, + 0.0, + -0.828125, + -0.5, + -0.8515625, + -0.9921875, + -0.03125, + -0.75, + -0.78125, + -0.59375, + -0.625, + 0.125, + -0.8359375, + 0.0, + 0.375, + 0.0, + 0.0, + 0.0, + -0.984375, + -0.9375, + -0.921875, + -0.125, + -0.890625, + -0.25, + -0.953125, + -0.859375, + 0.0, + 0.0, + 0.0, + -0.9296875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.125, + 0.890625, + 0.0, + -0.75, + -0.0078125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.34375, + -0.890625, + -0.5859375, + 0.0, + 0.0, + -0.078125, + -0.9375, + 0.0, + -0.6484375, + -0.921875, + 0.0, + 0.953125, + -0.8046875, + 0.375, + -0.859375, + 0.0, + -0.984375, + -0.9765625, + -0.71875, + -0.96875, + 0.0, + -0.84375, + 0.0, + -0.921875, + 0.0, + 0.0, + -0.25, + 0.0, + 0.0, + 0.0, + -0.8046875, + 0.0, + 0.2265625, + 0.0, + 0.0, + -0.9609375, + 0.0, + 0.3671875, + -0.34375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + -0.71875, + -0.9375, + -0.8671875, + -0.5, + 0.15625, + 0.0, + 0.0, + 0.875, + -0.515625, + 0.7421875, + 0.0, + -0.90625, + 0.0, + 0.0, + 0.0, + 0.25, + -0.9140625, + -0.5, + -0.90625, + -0.71875, + -0.9375, + 0.0, + -0.984375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.90625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.78125, + 0.0, + -0.75, + -0.953125, + 0.0, + 0.0, + 0.140625, + 0.0, + 0.75, + -0.828125, + 0.0, + 0.0, + 0.0, + -0.71875, + 0.0, + -0.9375, + 0.0, + -0.40625, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.0, + -0.9375, + 0.5, + -0.953125, + -0.375, + 0.0, + -0.515625, + -0.90625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.7578125, + 0.0, + -0.90625, + -0.9140625, + -0.5, + -0.75, + 0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.4375, + 0.0, + 0.0, + 0.0, + -0.953125, + -0.984375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.46875, + 0.0, + 0.2109375, + 0.0, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.890625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 47612.2852, + 29681.9785, + 9685.02344, + 10366.6133, + 25320.9473, + 1228.08594, + 2548.57544, + 7827.03906, + 3474.54419, + 16072.7373, + 3810.37109, + 448.523438, + 1589.68555, + 5381.83496, + 836.277344, + 771.416016, + 5027.05469, + 4482.10254, + 1866.13037, + 6280.17773, + 8842.2002, + 4198.9707, + 1138.6582, + -0.0, + -0.537631691, + 1105.33984, + -0.0, + 353.580078, + 803.046387, + 0.300319463, + -0.0, + -0.0938545391, + 788.500122, + 2058.97266, + 689.656738, + 1786.36084, + 2827.97729, + -0.0, + 384.125977, + 2484.40234, + 1275.76978, + 3062.03564, + 4230.07324, + 653.167847, + 0.3770459, + 602.042969, + 654.85791, + -0.0, + 183.375488, + -0.0, + -0.495024532, + 583.134399, + 149.6315, + 264.609375, + -0.0, + 1962.34375, + -0.0, + 141.37265, + 383.158142, + 521.482361, + 1284.00366, + 1356.92578, + 762.863342, + 0.462529421, + -0.0, + 1226.67383, + 2324.83008, + 499.091553, + 749.991211, + 2425.25195, + 2377.30225, + 2675.17139, + 1019.05859, + 132.942139, + -0.0, + 0.545760512, + -0.0, + 594.662598, + 0.413644016, + -0.0, + -0.373047233, + -0.0, + 0.374346316, + -0.0, + 115.903839, + -0.0, + 128.232788, + 135.698257, + 951.621094, + 316.103302, + -0.0, + 274.603516, + -0.0, + 152.435272, + 507.654999, + 201.013184, + 806.563171, + 680.23584, + 640.773621, + 179.730469, + 271.154205, + 698.474731, + 432.990723, + 599.71875, + -0.0, + 271.84436, + -0.0, + 0.370320976, + -0.0, + 1481.92212, + 1393.50049, + 2786.93091, + 787.924683, + 852.653809, + 2811.87402, + 1023.48145, + 203.506012, + -0.0, + -0.466360897, + -0.0, + 151.607849, + -0.0, + -0.186395302, + -0.0, + 0.1697689, + -0.0, + 0.14108035, + -0.0, + 0.506334126, + -0.0, + -0.212650388, + -0.0, + 0.312999606, + -0.198650092, + -0.0, + 0.148870453, + -0.0, + -0.442094564, + -0.0, + 335.137421, + 153.36554, + 434.610352, + -0.0, + 296.889709, + 831.954224, + -0.0, + -0.250246435, + 0.196501672, + -0.0, + 144.384766, + 285.338715, + 169.029785, + -0.0, + -0.0, + 319.300781, + 256.131592, + -0.0, + 2506.6582, + 866.978271, + -0.0, + 1004.13428, + 851.869751, + 1882.7085, + 486.026611, + -0.0, + 1501.50146, + 1168.18945, + 1274.10132, + 1316.84448, + -0.0, + 845.104492, + -0.0, + 363.010376, + 0.236458704, + -0.0, + 186.006073, + -0.0, + -0.242320612, + -0.0, + 190.222656, + -0.0, + 435.756287, + -0.0, + -0.0, + 428.566162, + -0.0, + 312.425415, + 357.086761, + -0.0, + -0.0, + -0.367251068, + -0.440564305, + -0.0, + -0.0, + 334.516357, + 244.190536, + 988.816406, + 1276.12439, + 193.717133, + 1228.79395, + -0.0, + -0.0362808965, + 505.596436, + 1264.62402, + 218.736542, + -0.0, + 135.690186, + -0.260842234, + -0.0, + -0.0, + 495.453125, + 936.823486, + 550.68927, + 1174.23071, + 352.294922, + 275.211914, + -0.0, + 153.442383, + -0.0, + 0.247258544, + -0.0, + -0.0, + 0.399930596, + -0.0, + 193.041199, + -0.0, + 0.445588857, + -0.236611947, + -0.0, + -0.0, + 323.139343, + -0.0, + 227.351318, + 150.857025, + -0.128424257, + -0.0, + 748.026367, + -0.0, + 478.079102, + 292.196228, + -0.0, + 0.477871299, + -0.0, + 613.836304, + -0.0, + 348.556641, + -0.0, + 202.474487, + -0.0840199366, + -0.0, + 0.28019616, + 168.475098, + -0.0, + 243.565674, + 123.423592, + 458.82193, + 453.447449, + -0.0, + 108.907227, + 279.82135, + -0.108905524, + -0.0, + -0.448157668, + -0.0, + -0.300282627, + -0.337572068, + -0.0, + 0.352406144, + -0.0, + 314.57959, + -0.0, + 107.710762, + 214.171265, + 340.737305, + 519.374207, + 616.277832, + -0.0, + -0.0, + 0.281172991, + 0.252057165, + -0.0, + -0.323162436, + -0.0, + 0.142856717, + -0.0, + -0.45232901, + -0.0, + -0.0, + 159.743652, + -0.102069773, + -0.0, + -0.174953684, + -0.0, + -0.0, + 667.668701, + -0.310068429, + -0.0, + -0.0, + 162.832336, + 170.938477, + -0.0, + -0.0, + -0.108819619, + 0.0756134614, + -0.0, + 169.365234, + -0.0, + 532.444519, + -0.0, + -0.353096187, + -0.0, + 134.797607, + -0.0, + 0.253662705, + -0.0, + -0.0, + 270.83844, + -0.0, + -0.251170784, + 0.249794334, + -0.0, + -0.0, + 0.416556954, + 0.180058807, + -0.0, + 0.294226915, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + -1, + -1, + 47, + -1, + 49, + 51, + -1, + -1, + -1, + 53, + 55, + 57, + 59, + 61, + -1, + 63, + 65, + 67, + 69, + 71, + 73, + -1, + 75, + 77, + -1, + 79, + -1, + -1, + 81, + 83, + 85, + -1, + 87, + -1, + 89, + 91, + 93, + 95, + 97, + 99, + -1, + -1, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + -1, + -1, + -1, + 119, + -1, + -1, + -1, + -1, + -1, + -1, + 121, + -1, + 123, + 125, + 127, + 129, + -1, + 131, + -1, + 133, + 135, + 137, + 139, + 141, + 143, + 145, + 147, + 149, + 151, + 153, + -1, + 155, + -1, + -1, + -1, + 157, + 159, + 161, + 163, + 165, + 167, + 169, + 171, + -1, + -1, + -1, + 173, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 175, + 177, + 179, + -1, + 181, + 183, + -1, + -1, + -1, + -1, + 185, + 187, + 189, + -1, + -1, + 191, + 193, + -1, + 195, + 197, + -1, + 199, + 201, + 203, + 205, + -1, + 207, + 209, + 211, + 213, + -1, + 215, + -1, + 217, + -1, + -1, + 219, + -1, + -1, + -1, + 221, + -1, + 223, + -1, + -1, + 225, + -1, + 227, + 229, + -1, + -1, + -1, + -1, + -1, + -1, + 231, + 233, + 235, + 237, + 239, + 241, + -1, + -1, + 243, + 245, + 247, + -1, + 249, + -1, + -1, + -1, + 251, + 253, + 255, + 257, + 259, + 261, + -1, + 263, + -1, + -1, + -1, + -1, + -1, + -1, + 265, + -1, + -1, + -1, + -1, + -1, + 267, + -1, + 269, + 271, + -1, + -1, + 273, + -1, + 275, + 277, + -1, + -1, + -1, + 279, + -1, + 281, + -1, + 283, + -1, + -1, + -1, + 285, + -1, + 287, + 289, + 291, + 293, + -1, + 295, + 297, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 299, + -1, + 301, + 303, + 305, + 307, + 309, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 311, + -1, + -1, + -1, + -1, + -1, + 313, + -1, + -1, + -1, + 315, + 317, + -1, + -1, + -1, + -1, + -1, + 319, + -1, + 321, + -1, + -1, + -1, + 323, + -1, + -1, + -1, + -1, + 325, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + -1, + -1, + 48, + -1, + 50, + 52, + -1, + -1, + -1, + 54, + 56, + 58, + 60, + 62, + -1, + 64, + 66, + 68, + 70, + 72, + 74, + -1, + 76, + 78, + -1, + 80, + -1, + -1, + 82, + 84, + 86, + -1, + 88, + -1, + 90, + 92, + 94, + 96, + 98, + 100, + -1, + -1, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + -1, + -1, + -1, + 120, + -1, + -1, + -1, + -1, + -1, + -1, + 122, + -1, + 124, + 126, + 128, + 130, + -1, + 132, + -1, + 134, + 136, + 138, + 140, + 142, + 144, + 146, + 148, + 150, + 152, + 154, + -1, + 156, + -1, + -1, + -1, + 158, + 160, + 162, + 164, + 166, + 168, + 170, + 172, + -1, + -1, + -1, + 174, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 176, + 178, + 180, + -1, + 182, + 184, + -1, + -1, + -1, + -1, + 186, + 188, + 190, + -1, + -1, + 192, + 194, + -1, + 196, + 198, + -1, + 200, + 202, + 204, + 206, + -1, + 208, + 210, + 212, + 214, + -1, + 216, + -1, + 218, + -1, + -1, + 220, + -1, + -1, + -1, + 222, + -1, + 224, + -1, + -1, + 226, + -1, + 228, + 230, + -1, + -1, + -1, + -1, + -1, + -1, + 232, + 234, + 236, + 238, + 240, + 242, + -1, + -1, + 244, + 246, + 248, + -1, + 250, + -1, + -1, + -1, + 252, + 254, + 256, + 258, + 260, + 262, + -1, + 264, + -1, + -1, + -1, + -1, + -1, + -1, + 266, + -1, + -1, + -1, + -1, + -1, + 268, + -1, + 270, + 272, + -1, + -1, + 274, + -1, + 276, + 278, + -1, + -1, + -1, + 280, + -1, + 282, + -1, + 284, + -1, + -1, + -1, + 286, + -1, + 288, + 290, + 292, + 294, + -1, + 296, + 298, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 300, + -1, + 302, + 304, + 306, + 308, + 310, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 312, + -1, + -1, + -1, + -1, + -1, + 314, + -1, + -1, + -1, + 316, + 318, + -1, + -1, + -1, + -1, + -1, + 320, + -1, + 322, + -1, + -1, + -1, + 324, + -1, + -1, + -1, + -1, + 326, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 8, + 2, + 1, + 0, + 2, + 5, + 4, + 5, + 7, + 5, + -2, + 6, + 9, + 0, + 6, + 6, + 10, + 7, + 6, + 6, + 7, + 0, + -2, + 8, + 0, + 1, + -2, + 5, + 8, + 10, + 7, + -2, + -2, + 1, + -2, + 6, + -2, + 1, + 10, + 10, + 0, + -2, + 0, + 0, + -2, + 0, + -2, + -2, + -2, + 10, + -2, + 10, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + 9, + 5, + 0, + 1, + 7, + -2, + 0, + -2, + 0, + 2, + 6, + -2, + 2, + 2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + 7, + 0, + 1, + 0, + 9, + 10, + 7, + 0, + 9, + -2, + -2, + -2, + 2, + 6, + 2, + 0, + 6, + -2, + 10, + 0, + -2, + -2, + -2, + -2, + 7, + 0, + -2, + 1, + 3, + -2, + 7, + -2, + 9, + 0, + 0, + -2, + -2, + -2, + 0, + 1, + 7, + 0, + 7, + 2, + -2, + 10, + -2, + 1, + -2, + 9, + 8, + -2, + -2, + 9, + -2, + 3, + 8, + 2, + -2, + -2, + -2, + 5, + 1, + -2, + 10, + -2, + -2, + -2, + 9, + -2, + 7, + -2, + 0, + 7, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + 7, + 7, + 0, + -2, + 10, + -2, + 10, + 6, + 0, + 3, + 6, + -2, + -2, + 10, + -2, + -2, + -2, + -2, + 7, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + 0, + 7, + -2, + 6, + 0, + 10, + 9, + 0, + -2, + -2, + 9, + -2, + 0, + 7, + -2, + 0, + -2, + 9, + -2, + 0, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + 7, + -2, + -2, + 0, + 1, + 0, + -2, + -2, + -2, + 9, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + 0, + -2, + 10, + 9, + 0, + 7, + 10, + -2, + -2, + -2, + 4, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + 6, + -2, + 6, + -2, + -2, + 7, + -2, + -2, + 5, + -2, + 6, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 10, + -2, + -2 + ], + "threshold": [ + -0.75, + -0.96875, + -0.59375, + -0.2890625, + 0.53125, + -0.5, + 0.0, + 0.25, + -0.9140625, + -0.625, + 0.0, + -0.796875, + 0.0, + -0.609375, + -0.7890625, + -0.9375, + -0.15625, + -0.9375, + -0.7734375, + -0.796875, + -0.921875, + -0.703125, + 0.0, + -0.375, + 0.1796875, + 0.875, + 0.0, + 0.25, + -0.5, + -0.90625, + -0.8359375, + 0.0, + 0.0, + -0.59375, + 0.0, + -0.9921875, + 0.0, + -0.21875, + 0.46875, + 0.21875, + -0.1171875, + 0.0, + 0.640625, + 0.1640625, + 0.0, + -0.703125, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.09375, + 0.0, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.5, + -0.921875, + 0.9375, + -0.578125, + 0.0, + -0.984375, + 0.0, + -0.7578125, + -0.9375, + -0.984375, + 0.0, + -0.71875, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1328125, + 0.0, + 0.0, + -0.921875, + 0.3828125, + -0.59375, + -0.0234375, + -0.75, + -0.96875, + -0.9765625, + -0.4140625, + -0.5, + 0.0, + 0.0, + 0.0, + -0.59375, + -0.953125, + -0.9375, + 0.421875, + -0.9921875, + 0.0, + 0.6875, + -0.078125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.1328125, + -0.7890625, + 0.0, + 0.59375, + 0.0, + 0.0, + -0.2421875, + 0.0, + -0.5, + 0.3828125, + 0.40625, + 0.0, + 0.0, + 0.0, + -0.8984375, + 0.78125, + -0.9453125, + -0.0703125, + 0.0859375, + -0.90625, + 0.0, + 0.625, + 0.0, + 0.9375, + 0.0, + -0.5, + -0.875, + 0.0, + 0.0, + 0.5, + 0.0, + 0.0, + -0.625, + -0.96875, + 0.0, + 0.0, + 0.0, + 0.75, + 0.9375, + 0.0, + 0.59375, + 0.0, + 0.0, + 0.0, + 0.25, + 0.0, + -0.75, + 0.0, + 0.890625, + -0.9609375, + -0.9453125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.890625, + 0.0, + -0.9375, + -0.953125, + -0.8125, + 0.0, + 0.1875, + 0.0, + -0.78125, + -0.9921875, + 0.75, + 0.0, + -0.8203125, + 0.0, + 0.0, + 0.3125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.78125, + 0.0, + -0.625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.4453125, + -0.9296875, + 0.0, + -0.9609375, + -0.2578125, + -0.75, + -0.5, + -0.796875, + 0.0, + 0.0, + 0.5, + 0.0, + 0.09375, + -0.859375, + 0.0, + -0.046875, + 0.0, + -0.5, + 0.0, + 0.4765625, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + -0.7734375, + 0.0, + 0.0, + -0.828125, + 0.78125, + -0.8046875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.75, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.75, + 0.0, + 0.0, + 0.0, + -0.640625, + 0.0, + -0.8125, + -0.5, + -0.34375, + -0.9609375, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8359375, + 0.0, + 0.0, + -0.953125, + 0.0, + -0.9921875, + 0.0, + 0.0, + -0.9453125, + 0.0, + 0.0, + 0.75, + 0.0, + -0.984375, + -0.921875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.0 + ], + "value": [ + 21581.9473, + 11696.9014, + 12733.8418, + 6322.71484, + 10168.9668, + 3757.51929, + 7936.02539, + 663.370178, + 7866.81836, + 6091.03369, + 0.43922472, + 830.942139, + 1844.15454, + 1623.84375, + 1092.09937, + 1205.56274, + 193.069336, + 2358.07617, + 2466.11841, + 5009.48145, + 1956.50305, + 1026.95508, + -0.0, + 514.93335, + 304.201752, + 103.968636, + -0.530897856, + 1872.4436, + 297.70755, + 994.672668, + 249.09903, + 0.137105852, + -0.0, + 140.401184, + 0.454757243, + 2806.93311, + 0.412512839, + 2998.9209, + 844.829834, + 1735.25635, + 909.105042, + -0.0, + 892.482422, + 936.989502, + -0.0, + 254.203857, + -0.0, + -0.103551216, + -0.0, + 1425.43115, + -0.0, + 563.643188, + -0.125743434, + 109.455383, + -0.194254741, + -0.0, + 0.194903001, + 0.114393309, + -0.0, + 1865.62036, + 534.679077, + 1811.89722, + 3019.11914, + 464.194092, + -0.0, + 675.594238, + -0.232122377, + 651.690063, + 993.6521, + 865.506348, + -0.0, + 1364.92639, + 797.168701, + -0.0, + -0.254838496, + -0.0, + -0.345485121, + 194.735535, + -0.0, + -0.0530830137, + 339.819855, + 1525.65527, + 206.148758, + 593.809998, + 813.676514, + 678.157959, + 1399.32288, + 1229.2041, + 773.769653, + -0.0, + 0.457972378, + -0.0, + 874.971191, + 200.239502, + 445.078125, + 711.979797, + 119.227173, + -0.0, + 325.489258, + 295.369476, + 0.276005119, + 0.425311059, + -0.0, + -0.0, + 258.560425, + 102.777252, + -0.0, + 934.317505, + 820.827637, + -0.0, + 177.367844, + -0.0, + 622.530151, + 720.14801, + 596.323303, + -0.0, + -0.172286198, + 0.359753758, + 765.989441, + 1227.82703, + 332.669922, + 274.668823, + 241.937729, + 615.483643, + 0.316010356, + 169.389832, + -0.0, + 232.303101, + -0.0, + 419.734894, + 558.559021, + -0.0, + -0.325381994, + 193.318359, + -0.0, + 201.701111, + 643.136475, + 255.18457, + -0.0, + -0.0, + 0.131105408, + 311.970642, + 657.481262, + -0.0, + 172.543457, + -0.183463886, + -0.0, + -0.0, + 280.469482, + -0.0, + 428.9198, + -0.0, + 711.300293, + 563.995728, + 1582.27234, + -0.235202789, + -0.0, + -0.0, + -0.407152236, + -0.0, + 0.302434444, + 291.594788, + -0.0, + 738.129395, + 341.909058, + 236.236969, + -0.0, + 187.673096, + -0.0, + 273.174622, + 972.438782, + 909.272339, + 682.284058, + 136.120117, + -0.0, + -0.0, + 220.070465, + -0.0, + -0.395501554, + -0.0, + 0.464847714, + 114.162964, + -0.0, + 134.034485, + -0.0, + 0.393740088, + -0.0, + -0.313431859, + -0.0, + 118.640381, + -0.0, + 0.42850557, + -0.0, + -0.0, + 0.194773406, + 1509.71948, + 1145.62341, + -0.0, + 171.322083, + 504.532745, + 710.532715, + 250.889771, + 841.875244, + -0.232283354, + -0.0, + 197.182617, + -0.0, + 266.996704, + 219.151306, + -0.0, + 116.756714, + 0.252692193, + 522.872498, + -0.0, + 291.179688, + -0.392429739, + -0.0, + 242.510468, + -0.0, + 0.282078713, + -0.0, + -0.47042796, + -0.0, + -0.0, + -0.388584346, + -0.279367208, + -0.0, + 577.635132, + 767.52417, + -0.257554263, + -0.0, + 211.08934, + 393.87384, + 429.993652, + -0.0, + -0.0, + 0.139661714, + 136.850281, + 108.028442, + 0.16797547, + -0.0, + -0.0, + -0.191659063, + -0.0, + 0.153164715, + -0.0, + -0.360379755, + -0.0, + 252.588379, + -0.0, + 0.388441831, + -0.0, + 118.131653, + -0.0, + 282.05127, + 375.629883, + 277.509918, + 170.032166, + 148.247269, + 0.285800338, + -0.0, + -0.0, + 204.143066, + 0.0701450258, + -0.0, + -0.229320124, + -0.0, + -0.339680254, + -0.0, + -0.0, + 0.176814586, + 267.301147, + -0.0, + -0.0, + 705.959717, + 0.0746575221, + 163.397446, + -0.0, + 0.0908388942, + 279.37262, + -0.0, + -0.0, + 263.428711, + -0.0, + 171.176392, + 326.243408, + -0.0, + -0.0, + -0.112965323, + -0.281230628, + -0.0, + 0.276521772, + -0.0, + 0.206724107, + -0.0, + -0.0, + 211.112549, + -0.0, + -0.265676767 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + -1, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + -1, + 43, + 45, + 47, + -1, + 49, + 51, + 53, + 55, + -1, + -1, + 57, + -1, + 59, + -1, + 61, + 63, + 65, + 67, + -1, + 69, + 71, + -1, + 73, + -1, + -1, + -1, + 75, + -1, + 77, + -1, + 79, + -1, + -1, + -1, + -1, + -1, + 81, + 83, + 85, + 87, + 89, + -1, + 91, + -1, + 93, + 95, + 97, + -1, + 99, + 101, + -1, + -1, + -1, + -1, + 103, + -1, + -1, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + -1, + -1, + -1, + 123, + 125, + 127, + 129, + 131, + -1, + 133, + 135, + -1, + -1, + -1, + -1, + 137, + 139, + -1, + 141, + 143, + -1, + 145, + -1, + 147, + 149, + 151, + -1, + -1, + -1, + 153, + 155, + 157, + 159, + 161, + 163, + -1, + 165, + -1, + 167, + -1, + 169, + 171, + -1, + -1, + 173, + -1, + 175, + 177, + 179, + -1, + -1, + -1, + 181, + 183, + -1, + 185, + -1, + -1, + -1, + 187, + -1, + 189, + -1, + 191, + 193, + 195, + -1, + -1, + -1, + -1, + -1, + -1, + 197, + -1, + 199, + 201, + 203, + -1, + 205, + -1, + 207, + 209, + 211, + 213, + 215, + -1, + -1, + 217, + -1, + -1, + -1, + -1, + 219, + -1, + 221, + -1, + -1, + -1, + -1, + -1, + 223, + -1, + -1, + -1, + -1, + -1, + 225, + 227, + -1, + 229, + 231, + 233, + 235, + 237, + -1, + -1, + 239, + -1, + 241, + 243, + -1, + 245, + -1, + 247, + -1, + 249, + -1, + -1, + 251, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 253, + 255, + -1, + -1, + 257, + 259, + 261, + -1, + -1, + -1, + 263, + 265, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 267, + -1, + -1, + -1, + 269, + -1, + 271, + 273, + 275, + 277, + 279, + -1, + -1, + -1, + 281, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 283, + -1, + -1, + 285, + -1, + 287, + -1, + -1, + 289, + -1, + -1, + 291, + -1, + 293, + 295, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 297, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + -1, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + -1, + 44, + 46, + 48, + -1, + 50, + 52, + 54, + 56, + -1, + -1, + 58, + -1, + 60, + -1, + 62, + 64, + 66, + 68, + -1, + 70, + 72, + -1, + 74, + -1, + -1, + -1, + 76, + -1, + 78, + -1, + 80, + -1, + -1, + -1, + -1, + -1, + 82, + 84, + 86, + 88, + 90, + -1, + 92, + -1, + 94, + 96, + 98, + -1, + 100, + 102, + -1, + -1, + -1, + -1, + 104, + -1, + -1, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + -1, + -1, + -1, + 124, + 126, + 128, + 130, + 132, + -1, + 134, + 136, + -1, + -1, + -1, + -1, + 138, + 140, + -1, + 142, + 144, + -1, + 146, + -1, + 148, + 150, + 152, + -1, + -1, + -1, + 154, + 156, + 158, + 160, + 162, + 164, + -1, + 166, + -1, + 168, + -1, + 170, + 172, + -1, + -1, + 174, + -1, + 176, + 178, + 180, + -1, + -1, + -1, + 182, + 184, + -1, + 186, + -1, + -1, + -1, + 188, + -1, + 190, + -1, + 192, + 194, + 196, + -1, + -1, + -1, + -1, + -1, + -1, + 198, + -1, + 200, + 202, + 204, + -1, + 206, + -1, + 208, + 210, + 212, + 214, + 216, + -1, + -1, + 218, + -1, + -1, + -1, + -1, + 220, + -1, + 222, + -1, + -1, + -1, + -1, + -1, + 224, + -1, + -1, + -1, + -1, + -1, + 226, + 228, + -1, + 230, + 232, + 234, + 236, + 238, + -1, + -1, + 240, + -1, + 242, + 244, + -1, + 246, + -1, + 248, + -1, + 250, + -1, + -1, + 252, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 254, + 256, + -1, + -1, + 258, + 260, + 262, + -1, + -1, + -1, + 264, + 266, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 268, + -1, + -1, + -1, + 270, + -1, + 272, + 274, + 276, + 278, + 280, + -1, + -1, + -1, + 282, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 284, + -1, + -1, + 286, + -1, + 288, + -1, + -1, + 290, + -1, + -1, + 292, + -1, + 294, + 296, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 298, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 8, + 5, + 5, + 6, + 2, + 6, + 9, + 7, + 10, + 10, + 10, + -2, + 7, + 2, + 0, + 0, + 1, + 6, + -2, + 0, + 9, + -2, + -2, + 10, + -2, + 2, + -2, + -2, + 2, + 7, + 7, + 7, + 7, + -2, + -2, + 7, + 4, + 6, + 10, + -2, + -2, + 10, + 0, + -2, + 7, + 7, + 10, + -2, + 6, + 10, + 2, + 6, + 2, + 0, + 10, + -2, + 5, + 1, + 7, + -2, + 6, + -2, + 10, + -2, + -2, + -2, + -2, + 0, + 8, + 0, + 7, + 5, + -2, + -2, + 2, + 0, + 0, + 1, + 0, + 6, + -2, + 0, + -2, + 5, + 0, + 7, + 9, + 0, + 0, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 10, + 0, + -2, + 4, + -2, + 10, + -2, + -2, + 7, + -2, + -2, + 8, + 6, + 7, + 7, + 7, + 7, + 10, + -2, + 7, + 2, + 10, + -2, + 10, + -2, + 8, + 6, + 0, + 10, + -2, + -2, + 7, + -2, + 7, + -2, + -2, + 0, + -2, + 7, + 7, + -2, + 0, + -2, + -2, + -2, + -2, + 0, + 6, + -2, + 6, + 2, + -2, + -2, + -2, + 0, + 7, + -2, + 6, + 10, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 8, + -2, + 1, + 1, + -2, + -2, + -2, + -2, + 2, + -2, + -2, + 9, + 5, + 5, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + 8, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + 7, + -2, + -2, + 0, + -2, + 10, + -2, + 10, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 0, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + 9, + 7, + -2, + -2, + -2, + 6, + 7, + -2, + -2, + 5, + -2, + -2, + 0, + -2, + -2, + -2, + 10, + 10, + 2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.625, + 0.0, + -0.375, + -0.5234375, + -0.40625, + -0.9765625, + -0.25, + -0.921875, + 0.8125, + -0.65625, + 0.125, + 0.0, + 0.4140625, + -0.75, + -0.6796875, + 0.484375, + -0.21875, + -0.4609375, + 0.0, + 0.421875, + 0.0, + 0.0, + 0.0, + 0.96875, + 0.0, + -0.9375, + 0.0, + 0.0, + -0.96875, + -0.9375, + -0.9609375, + -0.890625, + -0.453125, + 0.0, + 0.0, + -0.8984375, + 0.0, + -0.84375, + -0.34375, + 0.0, + 0.0, + -0.8125, + -0.296875, + 0.0, + -0.2421875, + -0.984375, + -0.875, + 0.0, + -0.984375, + -0.9375, + -0.9375, + -0.90625, + -0.9375, + 0.2421875, + -0.8125, + 0.0, + 0.25, + 0.21875, + -0.1171875, + 0.0, + -0.921875, + 0.0, + 0.15625, + 0.0, + 0.0, + 0.0, + 0.0, + -0.953125, + -0.875, + -0.7421875, + -0.9296875, + -0.25, + 0.0, + 0.0, + -0.8125, + -0.7734375, + -0.65625, + 0.96875, + -0.2890625, + -0.765625, + 0.0, + -0.609375, + 0.0, + 0.75, + -0.21875, + -0.890625, + 0.0, + 0.078125, + 0.1953125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.046875, + 0.0, + 0.0, + 0.0, + -0.625, + -0.8984375, + 0.0, + 0.0, + 0.0, + -0.125, + 0.0, + 0.0, + -0.90625, + 0.0, + 0.0, + -0.875, + -0.9375, + -0.609375, + -0.9140625, + -0.796875, + -0.84375, + 0.28125, + 0.0, + 0.1171875, + -0.875, + -0.71875, + 0.0, + -0.96875, + 0.0, + -0.75, + -0.984375, + 0.796875, + -0.75, + 0.0, + 0.0, + -0.7578125, + 0.0, + -0.5078125, + 0.0, + 0.0, + -0.4453125, + 0.0, + -0.9609375, + -0.9765625, + 0.0, + 0.4375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.4296875, + -0.9453125, + 0.0, + -0.8515625, + -0.78125, + 0.0, + 0.0, + 0.0, + 0.3671875, + -0.6484375, + 0.0, + -0.7578125, + -0.78125, + 0.0, + 0.0, + 0.0, + -0.953125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.1953125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.453125, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.28125, + 0.78125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.90625, + 0.0, + 0.0, + -0.25, + -0.25, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.25, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + 0.75, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9765625, + -0.9453125, + 0.0, + 0.0, + -0.6328125, + 0.0, + 0.90625, + 0.0, + 0.625, + 0.0, + 0.1875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.921875, + 0.0, + -0.875, + -0.828125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.34375, + 0.0, + -0.7890625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.0, + 0.0, + 0.0, + -0.9140625, + -0.9609375, + 0.0, + 0.0, + -0.125, + 0.0, + 0.0, + -0.96875, + 0.0, + 0.0, + 0.0, + -0.84375, + -0.875, + -0.625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 9841.97168, + 5682.89893, + 3112.37793, + 5863.40039, + 2389.4458, + 565.110352, + 1334.16003, + 4570.67529, + 153.792969, + 1545.66431, + 403.177734, + -0.0, + 343.264648, + 333.384155, + 452.349731, + 7417.25684, + 4714.6748, + 211.861328, + -0.0, + 1121.9707, + 599.309265, + 0.375016481, + -0.0, + 183.724609, + -0.0, + 1230.01721, + 0.151276574, + -0.0, + 394.887207, + 3403.38794, + 2361.78613, + 1386.09277, + 3922.71387, + -0.0, + 0.535359502, + 1808.58459, + 901.759277, + 528.332825, + 307.024414, + -0.360571891, + -0.0, + 475.931488, + 270.726807, + -0.0, + 200.928711, + 2516.03223, + 2261.14771, + -0.0, + 695.669922, + 169.546021, + 542.084229, + 1179.8457, + 444.45874, + 710.459229, + 731.739258, + -0.0, + 1316.73486, + 107.662514, + 197.348633, + -0.0, + 360.120422, + -0.0, + 491.163818, + -0.0, + -0.287125051, + -0.309937537, + -0.0, + 1642.94055, + 1324.71777, + 1143.66211, + 181.98584, + 122.196289, + -0.0, + -0.0, + 320.657837, + 272.411072, + 605.142578, + 1591.875, + 884.674805, + 899.048706, + -0.157605901, + 1001.0835, + -0.0, + 821.381714, + 262.837708, + 185.016266, + 1611.02246, + 417.684143, + 529.023132, + 0.258799881, + -0.0, + -0.277135432, + -0.0, + 420.33313, + -0.0, + -0.0, + 0.433287859, + 2468.75806, + 2830.69775, + -0.0, + 1155.86572, + -0.0, + 194.755249, + 0.546890259, + -0.0, + 237.610474, + -0.0, + -0.0, + 135.128174, + 119.248238, + 399.993103, + 1383.32422, + 109.31086, + 283.086731, + 512.236267, + -0.0, + 300.861084, + 141.873123, + 122.408691, + -0.0, + 210.453125, + -0.0, + 295.622589, + 172.160004, + 358.423096, + 140.883301, + -0.0, + -0.0, + 352.356171, + -0.0, + 559.782959, + -0.0, + 0.326604277, + 722.774292, + -0.247033611, + 165.209656, + 1033.60889, + -0.0, + 575.705566, + -0.199102476, + -0.0, + -0.243093207, + -0.0, + 512.191711, + 626.771301, + -0.0, + 214.88031, + 149.984741, + -0.0, + -0.0, + -0.366890609, + 119.997513, + 116.703453, + -0.0, + 178.632935, + 225.852661, + -0.0, + 0.332955539, + -0.0, + 286.129822, + -0.0, + 0.207135379, + -0.0, + -0.0, + 279.365723, + 0.207763538, + -0.0, + 0.191413149, + -0.0, + -0.353207141, + -0.0, + 129.704102, + -0.0, + -0.0, + 0.292148143, + 552.181641, + -0.0, + 596.840332, + 1240.03247, + -0.0230687186, + 0.087433733, + -0.0, + -0.331221312, + 336.13916, + -0.0, + -0.0, + 795.79248, + 267.099579, + 497.446838, + 0.127030775, + -0.0, + -0.211774766, + -0.0, + -0.0, + 314.864075, + -0.170411408, + -0.0, + 164.387268, + -0.0, + -0.0, + -0.290580541, + -0.0, + 178.740784, + -0.0, + -0.505128086, + -0.0, + 0.486382067, + -0.295461953, + -0.0, + 208.480957, + 167.12854, + 0.280864239, + -0.0, + 289.824707, + -0.0, + 583.537598, + -0.0, + 239.165924, + -0.0, + 325.40155, + -0.0, + 0.267773032, + -0.0, + 0.329307824, + -0.0, + 155.277161, + -0.0, + 1666.44263, + 1150.53857, + -0.20578441, + -0.0, + -0.0, + 0.260907948, + 0.306038201, + -0.0, + 105.961182, + -0.0, + 109.115356, + -0.0, + -0.0, + 0.130306587, + -0.309103698, + 0.145897016, + 1062.49487, + 448.966858, + -0.190739781, + -0.0, + -0.0, + 142.514282, + 369.408936, + -0.06269788, + -0.0, + 124.058105, + -0.0, + 0.21643953, + 1548.91748, + 0.160375312, + -0.153041482, + -0.0, + 530.76593, + 157.093872, + 153.75708, + -0.0, + -0.216746137, + -0.0, + 0.355227441, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + -1, + 23, + 25, + 27, + 29, + 31, + 33, + -1, + 35, + 37, + -1, + -1, + 39, + -1, + 41, + -1, + -1, + 43, + 45, + 47, + 49, + 51, + -1, + -1, + 53, + 55, + 57, + 59, + -1, + -1, + 61, + 63, + -1, + 65, + 67, + 69, + -1, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + -1, + 85, + 87, + 89, + -1, + 91, + -1, + 93, + -1, + -1, + -1, + -1, + 95, + 97, + 99, + 101, + 103, + -1, + -1, + 105, + 107, + 109, + 111, + 113, + 115, + -1, + 117, + -1, + 119, + 121, + 123, + 125, + 127, + 129, + -1, + -1, + -1, + -1, + 131, + -1, + -1, + -1, + 133, + 135, + -1, + 137, + -1, + 139, + -1, + -1, + 141, + -1, + -1, + 143, + 145, + 147, + 149, + 151, + 153, + 155, + -1, + 157, + 159, + 161, + -1, + 163, + -1, + 165, + 167, + 169, + 171, + -1, + -1, + 173, + -1, + 175, + -1, + -1, + 177, + -1, + 179, + 181, + -1, + 183, + -1, + -1, + -1, + -1, + 185, + 187, + -1, + 189, + 191, + -1, + -1, + -1, + 193, + 195, + -1, + 197, + 199, + -1, + -1, + -1, + 201, + -1, + -1, + -1, + -1, + 203, + -1, + -1, + -1, + -1, + -1, + -1, + 205, + -1, + -1, + -1, + 207, + -1, + 209, + 211, + -1, + -1, + -1, + -1, + 213, + -1, + -1, + 215, + 217, + 219, + -1, + -1, + -1, + -1, + -1, + 221, + -1, + -1, + 223, + -1, + -1, + -1, + -1, + 225, + -1, + -1, + -1, + -1, + -1, + -1, + 227, + 229, + -1, + -1, + 231, + -1, + 233, + -1, + 235, + -1, + 237, + -1, + -1, + -1, + -1, + -1, + 239, + -1, + 241, + 243, + -1, + -1, + -1, + -1, + -1, + -1, + 245, + -1, + 247, + -1, + -1, + -1, + -1, + -1, + 249, + 251, + -1, + -1, + -1, + 253, + 255, + -1, + -1, + 257, + -1, + -1, + 259, + -1, + -1, + -1, + 261, + 263, + 265, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + -1, + 24, + 26, + 28, + 30, + 32, + 34, + -1, + 36, + 38, + -1, + -1, + 40, + -1, + 42, + -1, + -1, + 44, + 46, + 48, + 50, + 52, + -1, + -1, + 54, + 56, + 58, + 60, + -1, + -1, + 62, + 64, + -1, + 66, + 68, + 70, + -1, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + -1, + 86, + 88, + 90, + -1, + 92, + -1, + 94, + -1, + -1, + -1, + -1, + 96, + 98, + 100, + 102, + 104, + -1, + -1, + 106, + 108, + 110, + 112, + 114, + 116, + -1, + 118, + -1, + 120, + 122, + 124, + 126, + 128, + 130, + -1, + -1, + -1, + -1, + 132, + -1, + -1, + -1, + 134, + 136, + -1, + 138, + -1, + 140, + -1, + -1, + 142, + -1, + -1, + 144, + 146, + 148, + 150, + 152, + 154, + 156, + -1, + 158, + 160, + 162, + -1, + 164, + -1, + 166, + 168, + 170, + 172, + -1, + -1, + 174, + -1, + 176, + -1, + -1, + 178, + -1, + 180, + 182, + -1, + 184, + -1, + -1, + -1, + -1, + 186, + 188, + -1, + 190, + 192, + -1, + -1, + -1, + 194, + 196, + -1, + 198, + 200, + -1, + -1, + -1, + 202, + -1, + -1, + -1, + -1, + 204, + -1, + -1, + -1, + -1, + -1, + -1, + 206, + -1, + -1, + -1, + 208, + -1, + 210, + 212, + -1, + -1, + -1, + -1, + 214, + -1, + -1, + 216, + 218, + 220, + -1, + -1, + -1, + -1, + -1, + 222, + -1, + -1, + 224, + -1, + -1, + -1, + -1, + 226, + -1, + -1, + -1, + -1, + -1, + -1, + 228, + 230, + -1, + -1, + 232, + -1, + 234, + -1, + 236, + -1, + 238, + -1, + -1, + -1, + -1, + -1, + 240, + -1, + 242, + 244, + -1, + -1, + -1, + -1, + -1, + -1, + 246, + -1, + 248, + -1, + -1, + -1, + -1, + -1, + 250, + 252, + -1, + -1, + -1, + 254, + 256, + -1, + -1, + 258, + -1, + -1, + 260, + -1, + -1, + -1, + 262, + 264, + 266, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 2, + 0, + 0, + 7, + 7, + 2, + 6, + 7, + 6, + 0, + 0, + 9, + -2, + 1, + 2, + 0, + 7, + 6, + -2, + -2, + 7, + 3, + 8, + 10, + 7, + 10, + 2, + -2, + -2, + -2, + 7, + 7, + 0, + 6, + -2, + -2, + 5, + -2, + 10, + 0, + 2, + 2, + 7, + 0, + 7, + 0, + -2, + -2, + -2, + -2, + 9, + 1, + 0, + 6, + 5, + 9, + -2, + -2, + -2, + 9, + -2, + 7, + 7, + -2, + -2, + 0, + 0, + 6, + -2, + -2, + 6, + 0, + -2, + -2, + 0, + 5, + -2, + -2, + 1, + -2, + 10, + 10, + 6, + 9, + 6, + -2, + -2, + -2, + -2, + 0, + 10, + -2, + 9, + 7, + 7, + -2, + 10, + -2, + -2, + 2, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + 7, + 10, + 7, + 7, + -2, + 7, + 7, + 9, + 5, + 1, + 8, + -2, + -2, + -2, + 0, + 3, + 7, + 6, + -2, + -2, + -2, + -2, + 1, + -2, + 6, + -2, + 0, + 7, + 9, + -2, + -2, + 7, + -2, + 7, + -2, + 7, + 10, + 7, + -2, + 10, + -2, + -2, + -2, + -2, + 10, + -2, + 7, + -2, + 0, + 7, + -2, + 0, + 2, + 8, + -2, + -2, + 4, + -2, + 1, + -2, + 10, + -2, + 7, + -2, + 8, + -2, + 6, + -2, + -2, + -2, + 5, + 0, + -2, + -2, + -2, + 8, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + 10, + -2, + -2, + 0, + -2, + 0, + -2, + -2, + 5, + 5, + -2, + -2, + -2, + 0, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + 7, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + 6, + -2, + -2, + -2, + -2, + 5, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.9375, + 0.421875, + -0.203125, + -0.2421875, + -0.9140625, + 0.78125, + -0.9921875, + -0.953125, + -0.3515625, + 0.4765625, + 0.6484375, + 0.0, + 0.0, + 0.53125, + -0.75, + -0.90625, + -0.921875, + -0.6171875, + 0.0, + 0.0, + -0.9375, + 0.0, + -0.625, + 0.25, + -0.96875, + -0.75, + -0.78125, + 0.0, + 0.0, + 0.0, + -0.96875, + -0.9375, + -0.046875, + -0.8515625, + 0.0, + 0.0, + 0.625, + 0.0, + 0.65625, + 0.8203125, + -0.96875, + -0.6875, + -0.859375, + -0.9375, + -0.765625, + -0.125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.25, + 0.84375, + -0.65625, + -0.9375, + -0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.25, + 0.0, + -0.78125, + -0.8984375, + 0.0, + 0.0, + -0.828125, + -0.828125, + -0.8203125, + 0.0, + 0.0, + -0.9921875, + -0.78125, + 0.0, + 0.0, + 0.6328125, + 0.375, + 0.0, + 0.0, + 0.9375, + 0.0, + -0.78125, + -0.53125, + -0.75, + -0.75, + -0.9921875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.7890625, + -0.3125, + 0.0, + 0.0, + -0.96875, + -0.9375, + 0.0, + -0.15625, + 0.0, + 0.0, + -0.84375, + 0.0, + -0.9765625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.75, + 0.0, + -0.859375, + -0.03125, + -0.859375, + -0.546875, + 0.0, + -0.890625, + -0.875, + -0.5, + -0.75, + 0.78125, + -0.75, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.0, + -0.9765625, + -0.9765625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.6875, + 0.0, + -0.984375, + 0.0, + -0.515625, + -0.6171875, + 0.0, + 0.0, + 0.0, + -0.3671875, + 0.0, + -0.3359375, + 0.0, + -0.296875, + -0.84375, + -0.703125, + 0.0, + -0.9375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.65625, + 0.0, + -0.9765625, + 0.0, + -0.9453125, + -0.9375, + 0.0, + -0.34375, + -0.875, + -0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.65625, + 0.0, + -0.5625, + 0.0, + -0.6015625, + 0.0, + -0.5, + 0.0, + -0.6328125, + 0.0, + 0.0, + 0.0, + 0.375, + 0.234375, + 0.0, + 0.0, + 0.0, + -0.625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9609375, + 0.0, + -0.125, + 0.0, + 0.0, + -0.4453125, + 0.0, + -0.6484375, + 0.0, + 0.0, + 0.625, + 0.375, + 0.0, + 0.0, + 0.0, + -0.7421875, + 0.0, + -0.9296875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + -0.828125, + 0.0, + 0.0, + -0.296875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9609375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.75, + 0.0, + -0.609375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 4794.57666, + 3419.15088, + 10815.8438, + 1802.88062, + 3596.29443, + 4601.96631, + 3295.08691, + 632.542542, + 666.99585, + 724.939941, + 1967.9187, + 2113.14697, + 0.356915474, + 1180.16248, + 2225.17383, + 158.773865, + 1328.83545, + 1401.44531, + -0.0, + -0.0, + 518.352539, + 1500.40015, + 1013.06274, + 926.29187, + 495.530273, + 473.812775, + 112.11499, + -0.411807597, + -0.0, + -0.0, + 597.416992, + 1020.7323, + 757.484253, + 232.067215, + 0.542694151, + -0.0, + 548.021484, + -0.0, + 1086.18555, + 1004.0658, + 1475.79297, + 1070.62878, + 831.84491, + 185.969788, + 658.602051, + 291.874573, + -0.0, + -0.217604086, + -0.0, + -0.0, + 338.572021, + 337.269226, + 985.024658, + 2320.71777, + 1676.40601, + 169.053772, + -0.0, + 0.521200716, + -0.0, + 328.981934, + -0.0, + 674.743225, + 671.32605, + -0.0, + -0.325152755, + 443.476257, + 1293.5177, + 315.114502, + -0.0, + -0.0832688883, + 415.076233, + 400.503906, + -0.0, + -0.0, + 117.702515, + 533.286011, + -0.0, + 0.00283807982, + 100.066589, + -0.0, + 595.652344, + 623.781128, + 598.611206, + 563.699463, + 553.32666, + -0.0, + 0.260735601, + 0.327989459, + -0.0, + 643.091431, + 667.20813, + -0.0, + 450.755127, + 849.070862, + 1927.09387, + -0.0, + 210.670654, + -0.224063888, + -0.0, + 116.658295, + -0.0, + 777.36792, + -0.283693612, + 0.350897074, + -0.0, + -0.283974349, + -0.0, + -0.212143421, + -0.0, + 595.911377, + -0.0, + 1176.42249, + 144.593384, + 498.539551, + 730.667847, + -0.0, + 539.543701, + 557.432739, + 283.606384, + 266.024109, + 464.265503, + 505.202393, + -0.0, + 0.246643931, + -0.0, + 365.798798, + 790.044983, + 467.438721, + 587.918457, + 0.273479015, + -0.0, + -0.0, + 0.25228247, + 130.871582, + -0.0, + 373.716309, + -0.0, + 383.7323, + 678.078613, + 235.331635, + -0.0364756063, + -0.0, + 450.027832, + -0.296502411, + 274.017975, + -0.0, + 542.587646, + 259.881836, + 256.912842, + -0.0, + 667.885742, + -0.0, + 0.278326482, + -0.373431027, + -0.0, + 148.200684, + -0.0, + 148.23999, + -0.212638602, + 182.286621, + 268.38266, + -0.0, + 225.083008, + 913.958984, + 261.017395, + -0.172327667, + -0.0, + 353.477051, + -0.0, + 241.442474, + -0.0, + 191.112793, + -0.0, + 317.896362, + -0.0, + 322.63916, + -0.0, + 597.693848, + -0.0, + -0.278250277, + -0.0, + 115.229584, + 289.33783, + 0.2726399, + -0.0, + -0.0, + 186.942627, + -0.0, + -0.330190361, + -0.0994954258, + 0.0711003169, + -0.0, + 329.086304, + 0.0281769112, + 371.508423, + -0.24674058, + -0.0, + 570.818481, + -0.050538674, + 173.756439, + -0.0, + -0.0, + 144.539062, + 162.239624, + -0.0, + -0.375532418, + -0.0, + 246.570496, + -0.0, + 249.964844, + -0.0, + 0.311254442, + -0.0, + 0.130811453, + -0.0, + -0.0, + -0.369105995, + -0.229210794, + -0.0, + -0.0, + 203.505615, + -0.186072111, + -0.0, + 654.422729, + -0.0, + -0.0, + 297.586609, + 0.221260771, + -0.0, + -0.200692922, + -0.0, + -0.0, + 480.565002, + -0.0, + 0.20972316, + -0.0, + 0.206367821, + 248.336914, + -0.0, + 193.197205, + -0.0, + 0.203487128, + -0.0, + 0.2327445, + -0.0, + -0.216322199, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + -1, + 25, + 27, + 29, + 31, + 33, + -1, + -1, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + -1, + -1, + -1, + 49, + 51, + 53, + 55, + -1, + -1, + 57, + -1, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + -1, + -1, + -1, + -1, + 75, + 77, + 79, + 81, + 83, + 85, + -1, + -1, + -1, + 87, + -1, + 89, + 91, + -1, + -1, + 93, + 95, + 97, + -1, + -1, + 99, + 101, + -1, + -1, + 103, + 105, + -1, + -1, + 107, + -1, + 109, + 111, + 113, + 115, + 117, + -1, + -1, + -1, + -1, + 119, + 121, + -1, + 123, + 125, + 127, + -1, + 129, + -1, + -1, + 131, + -1, + 133, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 135, + -1, + 137, + 139, + 141, + 143, + -1, + 145, + 147, + 149, + 151, + 153, + 155, + -1, + -1, + -1, + 157, + 159, + 161, + 163, + -1, + -1, + -1, + -1, + 165, + -1, + 167, + -1, + 169, + 171, + 173, + -1, + -1, + 175, + -1, + 177, + -1, + 179, + 181, + 183, + -1, + 185, + -1, + -1, + -1, + -1, + 187, + -1, + 189, + -1, + 191, + 193, + -1, + 195, + 197, + 199, + -1, + -1, + 201, + -1, + 203, + -1, + 205, + -1, + 207, + -1, + 209, + -1, + 211, + -1, + -1, + -1, + 213, + 215, + -1, + -1, + -1, + 217, + -1, + -1, + -1, + -1, + -1, + 219, + -1, + 221, + -1, + -1, + 223, + -1, + 225, + -1, + -1, + 227, + 229, + -1, + -1, + -1, + 231, + -1, + 233, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 235, + -1, + -1, + 237, + -1, + -1, + 239, + -1, + -1, + -1, + -1, + -1, + 241, + -1, + -1, + -1, + -1, + 243, + -1, + 245, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + -1, + 26, + 28, + 30, + 32, + 34, + -1, + -1, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + -1, + -1, + -1, + 50, + 52, + 54, + 56, + -1, + -1, + 58, + -1, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + -1, + -1, + -1, + -1, + 76, + 78, + 80, + 82, + 84, + 86, + -1, + -1, + -1, + 88, + -1, + 90, + 92, + -1, + -1, + 94, + 96, + 98, + -1, + -1, + 100, + 102, + -1, + -1, + 104, + 106, + -1, + -1, + 108, + -1, + 110, + 112, + 114, + 116, + 118, + -1, + -1, + -1, + -1, + 120, + 122, + -1, + 124, + 126, + 128, + -1, + 130, + -1, + -1, + 132, + -1, + 134, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 136, + -1, + 138, + 140, + 142, + 144, + -1, + 146, + 148, + 150, + 152, + 154, + 156, + -1, + -1, + -1, + 158, + 160, + 162, + 164, + -1, + -1, + -1, + -1, + 166, + -1, + 168, + -1, + 170, + 172, + 174, + -1, + -1, + 176, + -1, + 178, + -1, + 180, + 182, + 184, + -1, + 186, + -1, + -1, + -1, + -1, + 188, + -1, + 190, + -1, + 192, + 194, + -1, + 196, + 198, + 200, + -1, + -1, + 202, + -1, + 204, + -1, + 206, + -1, + 208, + -1, + 210, + -1, + 212, + -1, + -1, + -1, + 214, + 216, + -1, + -1, + -1, + 218, + -1, + -1, + -1, + -1, + -1, + 220, + -1, + 222, + -1, + -1, + 224, + -1, + 226, + -1, + -1, + 228, + 230, + -1, + -1, + -1, + 232, + -1, + 234, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 236, + -1, + -1, + 238, + -1, + -1, + 240, + -1, + -1, + -1, + -1, + -1, + 242, + -1, + -1, + -1, + -1, + 244, + -1, + 246, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 5, + 8, + 2, + 6, + 3, + 2, + 0, + 7, + 10, + 0, + 9, + 0, + 5, + 10, + -2, + 0, + 6, + -2, + -2, + -2, + 6, + 0, + 7, + -2, + 5, + 8, + 10, + -2, + -2, + 0, + 6, + 7, + 0, + -2, + -2, + 2, + 0, + 0, + -2, + 10, + 1, + 6, + 0, + -2, + 7, + 2, + 7, + 7, + -2, + 9, + 1, + 6, + 7, + 0, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 0, + 10, + 7, + 9, + -2, + 9, + -2, + -2, + 5, + -2, + -2, + 7, + -2, + 0, + 6, + 2, + -2, + 1, + 7, + 7, + 10, + 1, + -2, + -2, + -2, + 3, + -2, + 9, + 0, + 7, + 5, + 1, + 2, + -2, + -2, + 2, + -2, + -2, + 0, + 10, + -2, + -2, + 0, + 7, + 6, + -2, + 10, + -2, + -2, + 7, + 2, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + 7, + 5, + 0, + -2, + -2, + -2, + -2, + -2, + 7, + 7, + -2, + -2, + 5, + 5, + -2, + 10, + 1, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + 9, + -2, + 1, + -2, + 7, + -2, + 0, + -2, + -2, + 5, + 10, + 9, + 0, + 7, + 1, + -2, + 10, + -2, + -2, + 0, + 10, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 8, + 10, + -2, + 7, + -2, + -2, + -2, + 7, + -2, + -2, + 8, + 9, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + 0, + -2, + 10, + -2, + -2, + -2, + 10, + -2, + -2, + 10, + -2, + -2, + 6, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + 7, + -2, + -2, + -2 + ], + "threshold": [ + -0.375, + -0.75, + -0.1875, + -0.6953125, + 0.0, + -0.96875, + -0.6953125, + -0.9296875, + 0.5, + -0.703125, + 0.0, + -0.125, + 0.875, + 0.0, + 0.0, + 0.25, + -0.9453125, + 0.0, + 0.0, + 0.0, + -0.984375, + 0.3515625, + -0.7109375, + 0.0, + 0.5, + -0.5, + -0.90625, + 0.0, + 0.0, + -0.984375, + -0.9921875, + -0.65625, + -0.5625, + 0.0, + 0.0, + -0.96875, + 0.859375, + -0.671875, + 0.0, + -0.25, + 0.6875, + -0.8359375, + -0.296875, + 0.0, + -0.6640625, + 0.96875, + -0.984375, + -0.9609375, + 0.0, + -0.5, + 0.40625, + -0.8984375, + -0.6953125, + -0.2890625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0078125, + 0.0, + 0.2578125, + -0.90625, + -0.8359375, + 0.25, + 0.0, + -0.75, + 0.0, + 0.0, + -0.5, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.390625, + -0.9921875, + -0.46875, + 0.0, + 0.96875, + -0.90625, + -0.7734375, + 0.15625, + 0.8125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + 0.125, + -0.7734375, + 0.25, + 0.96875, + -0.9375, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + -0.890625, + -0.96875, + 0.0, + 0.0, + -0.2734375, + -0.921875, + -0.953125, + 0.0, + -0.75, + 0.0, + 0.0, + -0.7265625, + -0.78125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.40625, + 0.0, + 0.0, + -0.8671875, + 0.625, + -0.0859375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.96875, + -0.96875, + 0.0, + 0.0, + -0.75, + -0.625, + 0.0, + -0.9375, + 0.96875, + 0.0, + 0.0, + -0.5859375, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.96875, + 0.0, + -0.9375, + 0.0, + 0.2265625, + 0.0, + 0.0, + 0.75, + -0.71875, + 0.0, + -0.7578125, + -0.9453125, + 0.8125, + 0.0, + -0.96875, + 0.0, + 0.0, + -0.8515625, + 0.6875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.625, + 0.375, + 0.0, + -0.2265625, + 0.0, + 0.0, + 0.0, + -0.9453125, + 0.0, + 0.0, + -0.875, + 0.25, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.8671875, + 0.0, + 0.25, + 0.0, + 0.0, + 0.0, + -0.90625, + 0.0, + 0.0, + -0.1875, + 0.0, + 0.0, + -0.9609375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9296875, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 2171.69238, + 2312.45996, + 1176.91833, + 1524.26941, + 2014.77539, + 1459.84375, + 120.614868, + 649.064758, + 470.128662, + 1960.43311, + 276.889984, + 1366.72754, + 462.924652, + 139.994507, + -0.0, + 745.094971, + 1165.96765, + 0.301143169, + -0.0, + -0.0, + 689.188965, + 155.960693, + 431.39563, + -0.0, + 933.302979, + 553.811035, + 497.393982, + 0.287917614, + -0.0, + 393.599518, + 797.037048, + 1123.18225, + 353.276855, + -0.0, + -0.380562991, + 653.810425, + 314.663086, + 113.156189, + -0.0, + 633.106445, + 559.667969, + 502.743011, + 400.949524, + -0.0, + 255.219543, + 158.664307, + 289.738403, + 898.669678, + -0.0, + 1280.90747, + 140.133347, + 399.380371, + 220.959259, + 479.081787, + -0.0, + 0.162245303, + -0.0, + -0.0, + -0.280652761, + 446.996582, + -0.0, + 420.05011, + 257.550354, + 529.440857, + 352.598907, + -0.0, + 273.928406, + 0.268477321, + -0.0, + 137.696655, + -0.0, + 0.163161099, + 128.355347, + -0.0, + 147.239014, + 308.893097, + 439.641602, + 0.0556487069, + 107.538918, + 322.517334, + 114.525848, + 110.585175, + 210.551483, + -0.0, + -0.299907953, + -0.0, + 265.280762, + -0.0, + 1262.79187, + 459.644714, + 133.582932, + 168.195343, + 196.950562, + 290.972229, + -0.0, + -0.0, + 197.770264, + -0.127364174, + -0.0, + 143.641617, + 196.622131, + -0.0, + 0.402136505, + 842.062378, + 473.472382, + 439.658203, + -0.0, + 196.225861, + -0.0, + -0.0, + 376.1073, + 124.492218, + 0.052758459, + -0.151553109, + -0.0, + -0.0, + 166.915649, + -0.0, + 0.346051216, + -0.0, + 0.419807702, + -0.0, + 694.942444, + 0.108465612, + -0.0, + 165.263916, + 226.144516, + 228.909607, + -0.0, + 0.262646824, + -0.0, + -0.255718738, + -0.0, + 1280.7168, + 588.601257, + 0.103039674, + -0.0, + 212.229645, + 807.188171, + -0.0, + 260.711304, + 375.401367, + -0.0, + -0.0, + 158.814667, + 0.236174911, + -0.0, + -0.134312168, + -0.0, + 184.004059, + -0.0, + 797.610596, + -0.0, + 103.129074, + 0.0526515208, + 173.424866, + -0.0, + -0.0, + 213.818726, + 160.120178, + 220.186707, + 535.852234, + 522.858643, + 139.454254, + -0.0, + 697.596069, + -0.0, + -0.0, + 159.110596, + 169.359863, + -0.0, + -0.0, + -0.146997213, + -0.0, + 0.218661949, + -0.658750236, + -0.0, + -0.0, + 181.52655, + 189.946899, + -0.0, + 240.6521, + -0.0, + -0.209037378, + -0.0, + 277.08075, + -0.0, + -0.0, + 307.193054, + 452.309082, + -0.0, + -0.104610629, + -0.0, + -0.0, + 0.333819151, + -0.0, + -0.232252881, + -0.198264301, + -0.0, + 112.444214, + -0.0, + 0.0846322551, + -0.0, + 264.468018, + -0.0, + 298.059814, + -0.0, + 0.320286572, + -0.0, + 112.303955, + -0.0, + -0.0, + 133.518738, + -0.224559799, + -0.0, + 159.176758, + -0.0, + -0.171542153, + -0.0, + 235.92334, + -0.0, + 0.157414511, + -0.0, + 179.404846, + -0.0, + -0.0, + -0.180934027 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + -1, + 29, + 31, + -1, + -1, + -1, + 33, + 35, + 37, + -1, + 39, + 41, + 43, + -1, + -1, + 45, + 47, + 49, + 51, + -1, + -1, + 53, + 55, + 57, + -1, + 59, + 61, + 63, + 65, + -1, + 67, + 69, + 71, + 73, + -1, + 75, + 77, + 79, + 81, + 83, + -1, + -1, + -1, + -1, + -1, + 85, + -1, + 87, + 89, + 91, + 93, + -1, + 95, + -1, + -1, + 97, + -1, + -1, + 99, + -1, + 101, + 103, + 105, + -1, + 107, + 109, + 111, + 113, + 115, + -1, + -1, + -1, + 117, + -1, + 119, + 121, + 123, + 125, + 127, + 129, + -1, + -1, + 131, + -1, + -1, + 133, + 135, + -1, + -1, + 137, + 139, + 141, + -1, + 143, + -1, + -1, + 145, + 147, + -1, + -1, + -1, + -1, + 149, + -1, + -1, + -1, + -1, + -1, + 151, + -1, + -1, + 153, + 155, + 157, + -1, + -1, + -1, + -1, + -1, + 159, + 161, + -1, + -1, + 163, + 165, + -1, + 167, + 169, + -1, + -1, + 171, + -1, + -1, + -1, + -1, + 173, + -1, + 175, + -1, + 177, + -1, + 179, + -1, + -1, + 181, + 183, + 185, + 187, + 189, + 191, + -1, + 193, + -1, + -1, + 195, + 197, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 199, + 201, + -1, + 203, + -1, + -1, + -1, + 205, + -1, + -1, + 207, + 209, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 211, + -1, + -1, + -1, + 213, + -1, + 215, + -1, + -1, + -1, + 217, + -1, + -1, + 219, + -1, + -1, + 221, + -1, + -1, + -1, + 223, + -1, + -1, + -1, + 225, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + -1, + 30, + 32, + -1, + -1, + -1, + 34, + 36, + 38, + -1, + 40, + 42, + 44, + -1, + -1, + 46, + 48, + 50, + 52, + -1, + -1, + 54, + 56, + 58, + -1, + 60, + 62, + 64, + 66, + -1, + 68, + 70, + 72, + 74, + -1, + 76, + 78, + 80, + 82, + 84, + -1, + -1, + -1, + -1, + -1, + 86, + -1, + 88, + 90, + 92, + 94, + -1, + 96, + -1, + -1, + 98, + -1, + -1, + 100, + -1, + 102, + 104, + 106, + -1, + 108, + 110, + 112, + 114, + 116, + -1, + -1, + -1, + 118, + -1, + 120, + 122, + 124, + 126, + 128, + 130, + -1, + -1, + 132, + -1, + -1, + 134, + 136, + -1, + -1, + 138, + 140, + 142, + -1, + 144, + -1, + -1, + 146, + 148, + -1, + -1, + -1, + -1, + 150, + -1, + -1, + -1, + -1, + -1, + 152, + -1, + -1, + 154, + 156, + 158, + -1, + -1, + -1, + -1, + -1, + 160, + 162, + -1, + -1, + 164, + 166, + -1, + 168, + 170, + -1, + -1, + 172, + -1, + -1, + -1, + -1, + 174, + -1, + 176, + -1, + 178, + -1, + 180, + -1, + -1, + 182, + 184, + 186, + 188, + 190, + 192, + -1, + 194, + -1, + -1, + 196, + 198, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 200, + 202, + -1, + 204, + -1, + -1, + -1, + 206, + -1, + -1, + 208, + 210, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 212, + -1, + -1, + -1, + 214, + -1, + 216, + -1, + -1, + -1, + 218, + -1, + -1, + 220, + -1, + -1, + 222, + -1, + -1, + -1, + 224, + -1, + -1, + -1, + 226, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 9, + 1, + 8, + 1, + 0, + 7, + 2, + 0, + 0, + -2, + 6, + 10, + 9, + 6, + 0, + 2, + 10, + 1, + 0, + 0, + 6, + 1, + 6, + 10, + -2, + 5, + 7, + -2, + -2, + 0, + 10, + 5, + 5, + 0, + 7, + 6, + -2, + 0, + 10, + 7, + 7, + 0, + 9, + 7, + 0, + 5, + -2, + 6, + -2, + -2, + 4, + 7, + 10, + -2, + 10, + 2, + 6, + 8, + 7, + -2, + 2, + 2, + 2, + -2, + -2, + 7, + -2, + 0, + -2, + -2, + 10, + -2, + -2, + 4, + 6, + 0, + 9, + -2, + 0, + 6, + 10, + 7, + -2, + -2, + 0, + -2, + 1, + 7, + 6, + 7, + 6, + 7, + -2, + -2, + -2, + 8, + 7, + -2, + 6, + -2, + 10, + -2, + -2, + 0, + -2, + -2, + 2, + 0, + -2, + -2, + -2, + 0, + -2, + 6, + 6, + 7, + -2, + -2, + 1, + 10, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 10, + 4, + -2, + 9, + 0, + 7, + 6, + -2, + -2, + 0, + -2, + 0, + 6, + 0, + -2, + -2, + -2, + -2, + -2, + 3, + -2, + -2, + 10, + -2, + -2, + 0, + -2, + -2, + -2, + 10, + -2, + 7, + -2, + 2, + -2, + 2, + -2, + 0, + -2, + -2, + -2, + 0, + -2, + -2, + 2, + 10, + 10, + -2, + -2, + 7, + 9, + -2, + 7, + 0, + 7, + -2, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2 + ], + "threshold": [ + -0.25, + 0.9375, + -0.75, + -0.15625, + -0.15625, + -0.5625, + -0.9375, + -0.3046875, + -0.1875, + 0.0, + -0.9921875, + -0.40625, + 0.5, + -0.859375, + -0.703125, + -0.5625, + -0.53125, + 0.75, + 0.796875, + 0.390625, + -0.9609375, + 0.25, + -0.96875, + 0.6875, + 0.0, + 0.5, + -0.6640625, + 0.0, + 0.0, + -0.921875, + -0.78125, + -0.875, + -0.75, + -0.90625, + -0.9375, + -0.59375, + 0.0, + 0.359375, + -0.25, + -0.90625, + -0.609375, + -0.1640625, + 0.25, + -0.8515625, + -0.59375, + -0.75, + 0.0, + -0.9765625, + 0.0, + 0.0, + 0.0, + -0.9453125, + -0.9375, + 0.0, + 0.03125, + -0.9375, + -0.96875, + -0.875, + -0.7578125, + 0.0, + -0.90625, + -0.625, + -0.96875, + 0.0, + 0.0, + -0.3984375, + 0.0, + 0.9375, + 0.0, + 0.0, + -0.625, + 0.0, + 0.0, + 0.0, + -0.9921875, + 0.640625, + 0.5, + 0.0, + -0.265625, + -0.9296875, + 0.53125, + -0.2734375, + 0.0, + 0.0, + -0.5390625, + 0.0, + 0.90625, + -0.9765625, + -0.9765625, + -0.953125, + -0.9765625, + -0.96875, + 0.0, + 0.0, + 0.0, + -0.875, + -0.859375, + 0.0, + -0.671875, + 0.0, + -0.40625, + 0.0, + 0.0, + -0.828125, + 0.0, + 0.0, + -0.875, + -0.078125, + 0.0, + 0.0, + 0.0, + 0.3203125, + 0.0, + -0.9921875, + -0.96875, + -0.7421875, + 0.0, + 0.0, + 0.96875, + -0.75, + 0.0, + 0.0, + 0.0, + -0.8515625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.84375, + 0.0, + 0.0, + -0.5, + -0.703125, + -0.875, + -0.921875, + 0.0, + 0.0, + 0.234375, + 0.0, + 0.03125, + -0.9140625, + -0.28125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9375, + 0.0, + 0.0, + -0.921875, + 0.0, + 0.0, + 0.0, + -0.65625, + 0.0, + -0.921875, + 0.0, + -0.84375, + 0.0, + -0.75, + 0.0, + -0.9453125, + 0.0, + 0.0, + 0.0, + -0.890625, + 0.0, + 0.0, + -0.96875, + -0.90625, + -0.375, + 0.0, + 0.0, + -0.8125, + -0.75, + 0.0, + -0.921875, + 0.078125, + -0.578125, + 0.0, + 0.0, + 0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9296875, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 1271.38269, + 2744.51855, + 2236.41724, + 2990.8208, + 663.598633, + 929.51416, + 1001.52539, + 803.124512, + 4475.94824, + -0.0, + 401.893311, + 1206.8103, + 353.267395, + 538.175964, + 898.212402, + 1032.38818, + 344.046997, + 981.832397, + 635.987793, + 284.704346, + 889.909546, + 215.939133, + 387.59375, + 516.861328, + -0.0, + 700.326904, + 117.034599, + -0.0, + -0.340765297, + 167.040024, + 752.349915, + 361.973511, + 315.818359, + 448.008759, + 1460.22888, + 388.413574, + -0.0, + 765.743774, + 377.311523, + 128.554092, + 1303.00012, + 628.7854, + 197.823486, + 254.044312, + 413.021698, + 599.332275, + -0.0, + 343.002563, + -0.0, + -0.0, + 212.022583, + 426.139435, + 255.815384, + -0.0, + 615.831665, + 548.238281, + 301.349823, + 256.597931, + 670.594543, + -0.0, + 142.749329, + 239.535583, + 830.797363, + -0.284998626, + -0.0, + 160.807861, + -0.0161003377, + 250.175293, + -0.0, + -0.0, + 475.838989, + 0.337458402, + -0.0, + 148.573746, + 720.725403, + 355.974884, + 527.745972, + -0.228092626, + 138.75975, + 174.394165, + 224.113525, + 191.438232, + -0.0, + -0.0, + 196.669067, + -0.0, + 210.088196, + 410.376526, + 142.312378, + 212.579254, + 374.628174, + 713.615234, + -0.0, + 0.306255102, + -0.0, + 181.854156, + 315.484619, + -0.0, + 497.589996, + -0.0, + 265.294739, + -0.0, + -0.235815644, + 208.528503, + -0.0, + -0.0, + 458.858398, + 286.422974, + -0.0, + 0.422078609, + -0.0, + 614.856934, + -0.0, + 236.164047, + 345.991486, + 430.784058, + -0.0, + -0.0, + 153.85144, + 595.791931, + -0.104743876, + -0.0, + -0.110438854, + 296.002014, + -0.0, + -0.178701311, + -0.0, + -0.0, + 0.36991033, + -0.0, + -0.292872965, + 0.181524664, + -0.0, + -0.159761935, + 202.586884, + 173.565491, + -0.0, + 491.847778, + 116.311058, + 395.009766, + 154.383362, + 0.435849756, + -0.0, + 703.328308, + -0.0209078528, + 535.323975, + 341.506775, + 199.118591, + -0.0, + -0.0, + 0.216054544, + -0.0, + -0.184381217, + 283.946533, + -0.0, + -0.0, + 263.098511, + -0.0, + -0.274697483, + 190.548462, + -0.0, + -0.0475586653, + 0.049588792, + 281.200073, + -0.0, + 160.734863, + -0.0, + 548.85907, + -0.0, + 314.795868, + -0.0, + 466.904663, + -0.0, + -0.0, + -0.243225798, + 182.720276, + -0.0, + 0.00613441877, + 122.114502, + 344.293579, + 136.96492, + -0.0590117387, + -0.0, + 243.550842, + 463.544006, + -0.0, + 240.534424, + 164.279556, + 160.805511, + -0.0, + -0.2162119, + 491.553223, + -0.0, + -0.0, + 0.318579912, + -0.0, + 0.196808651, + 0.341684878, + -0.0, + -0.0, + -0.297296315, + 0.360154271, + -0.0, + 0.273624897, + -0.0, + 0.139855757, + -0.0, + -0.0, + -0.335382879, + -0.0, + -0.0738624334, + -0.0, + 357.296143, + -0.100411355, + -0.0, + 0.154614091, + -0.0, + 0.0211656783, + 673.945374, + -0.0, + 0.528304756, + -0.0, + -0.140439644, + 0.211793423, + -0.0, + 0.385128826, + -0.0, + -0.0, + 0.157900289, + 1270.04443, + -0.0, + -0.0, + -0.446851552 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + -1, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + -1, + 47, + 49, + -1, + -1, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + -1, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + -1, + 83, + -1, + -1, + 85, + 87, + 89, + -1, + 91, + 93, + 95, + 97, + 99, + -1, + 101, + 103, + 105, + -1, + -1, + 107, + -1, + 109, + -1, + -1, + 111, + -1, + -1, + 113, + 115, + 117, + 119, + -1, + 121, + 123, + 125, + 127, + -1, + -1, + 129, + -1, + 131, + 133, + 135, + 137, + 139, + 141, + -1, + -1, + -1, + 143, + 145, + -1, + 147, + -1, + 149, + -1, + -1, + 151, + -1, + -1, + 153, + 155, + -1, + -1, + -1, + 157, + -1, + 159, + 161, + 163, + -1, + -1, + 165, + 167, + -1, + -1, + -1, + 169, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 171, + 173, + -1, + 175, + 177, + 179, + 181, + -1, + -1, + 183, + -1, + 185, + 187, + 189, + -1, + -1, + -1, + -1, + -1, + 191, + -1, + -1, + 193, + -1, + -1, + 195, + -1, + -1, + -1, + 197, + -1, + 199, + -1, + 201, + -1, + 203, + -1, + 205, + -1, + -1, + -1, + 207, + -1, + -1, + 209, + 211, + 213, + -1, + -1, + 215, + 217, + -1, + 219, + 221, + 223, + -1, + -1, + 225, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 227, + -1, + -1, + -1, + -1, + -1, + 229, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 231, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + -1, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + -1, + 48, + 50, + -1, + -1, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + -1, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + -1, + 84, + -1, + -1, + 86, + 88, + 90, + -1, + 92, + 94, + 96, + 98, + 100, + -1, + 102, + 104, + 106, + -1, + -1, + 108, + -1, + 110, + -1, + -1, + 112, + -1, + -1, + 114, + 116, + 118, + 120, + -1, + 122, + 124, + 126, + 128, + -1, + -1, + 130, + -1, + 132, + 134, + 136, + 138, + 140, + 142, + -1, + -1, + -1, + 144, + 146, + -1, + 148, + -1, + 150, + -1, + -1, + 152, + -1, + -1, + 154, + 156, + -1, + -1, + -1, + 158, + -1, + 160, + 162, + 164, + -1, + -1, + 166, + 168, + -1, + -1, + -1, + 170, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 172, + 174, + -1, + 176, + 178, + 180, + 182, + -1, + -1, + 184, + -1, + 186, + 188, + 190, + -1, + -1, + -1, + -1, + -1, + 192, + -1, + -1, + 194, + -1, + -1, + 196, + -1, + -1, + -1, + 198, + -1, + 200, + -1, + 202, + -1, + 204, + -1, + 206, + -1, + -1, + -1, + 208, + -1, + -1, + 210, + 212, + 214, + -1, + -1, + 216, + 218, + -1, + 220, + 222, + 224, + -1, + -1, + 226, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 228, + -1, + -1, + -1, + -1, + -1, + 230, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 232, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 9, + 1, + 1, + 1, + 7, + 0, + 7, + 0, + 0, + 7, + 7, + 2, + 6, + 7, + -2, + 4, + 2, + 1, + 6, + -2, + 0, + 6, + 0, + 7, + -2, + 7, + 6, + -2, + 10, + 6, + 0, + 10, + -2, + 2, + 4, + 9, + -2, + -2, + -2, + 0, + -2, + -2, + 5, + -2, + -2, + 10, + -2, + 5, + -2, + -2, + 0, + 6, + -2, + 7, + 7, + -2, + 10, + -2, + 0, + 7, + -2, + 5, + 7, + -2, + -2, + -2, + -2, + 0, + -2, + 7, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 6, + 10, + 7, + -2, + -2, + -2, + -2, + -2, + 0, + 6, + -2, + 10, + -2, + -2, + -2, + -2, + -2, + 10, + 7, + 5, + 6, + -2, + 10, + 10, + -2, + 0, + 0, + 1, + -2, + -2, + -2, + 0, + 10, + 5, + 7, + -2, + -2, + -2, + 5, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 6, + 2, + -2, + -2, + -2 + ], + "threshold": [ + 0.0, + 0.9375, + -0.59375, + 0.21875, + -0.90625, + -0.8046875, + -0.4453125, + 0.25, + -0.1015625, + -0.9375, + -0.6953125, + 0.96875, + -0.9921875, + -0.9375, + 0.0, + 0.0, + -0.9375, + 0.84375, + -0.59375, + 0.0, + 0.015625, + -0.9609375, + 0.328125, + -0.9375, + 0.0, + -0.1953125, + -0.9296875, + 0.0, + -0.9375, + -0.859375, + -0.921875, + -0.96875, + 0.0, + -0.875, + 0.0, + -0.5, + 0.0, + 0.0, + 0.0, + 0.3515625, + 0.0, + 0.0, + 0.5, + 0.0, + 0.0, + -0.15625, + 0.0, + 0.375, + 0.0, + 0.0, + -0.796875, + -0.984375, + 0.0, + -0.9453125, + -0.71875, + 0.0, + 0.9375, + 0.0, + -0.8671875, + -0.71875, + 0.0, + -0.375, + -0.9453125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.7890625, + 0.0, + -0.4375, + 0.0, + 0.0, + 0.0, + -0.9453125, + 0.0, + 0.0, + 0.0, + -0.8671875, + -0.125, + -0.796875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.03125, + -0.9921875, + 0.0, + -0.96875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.96875, + -0.953125, + 0.625, + -0.7109375, + 0.0, + -0.71875, + -0.75, + 0.0, + 0.7578125, + 0.2109375, + 0.90625, + 0.0, + 0.0, + 0.0, + -0.8828125, + -0.9375, + 0.625, + -0.7421875, + 0.0, + 0.0, + 0.0, + 0.125, + 0.0, + 0.0, + 0.3125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9140625, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.9609375, + -0.875, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 820.657227, + 839.154053, + 944.916443, + 1474.54211, + 649.337158, + 108.05027, + 634.690308, + 1209.18469, + 1811.12549, + 857.748291, + 554.225281, + 144.525589, + 527.491821, + 605.428223, + -0.0, + 402.585205, + 310.328979, + 156.422455, + 405.52832, + -0.0, + 560.020752, + 271.703979, + 681.375549, + 174.326233, + -0.0, + 174.205383, + 450.203369, + -0.0, + 305.651855, + 662.231201, + 192.056839, + 444.419312, + -0.0, + 121.619995, + 610.989258, + 478.373535, + -0.0, + -0.0, + 0.317403466, + 211.139343, + -0.0, + -0.0, + 172.846069, + -0.0830149427, + -0.0, + 153.074158, + -0.0, + 219.400787, + 0.00194426719, + -0.0, + 280.752197, + 194.290726, + 0.236259177, + 121.722824, + 153.226837, + -0.0, + 414.567871, + -0.0, + 641.887939, + 115.296936, + -0.0, + 450.848511, + 598.746582, + -0.0, + -0.116204776, + 0.24685055, + -0.0, + 136.17627, + -0.0, + 211.5224, + -0.0, + -0.0, + -0.222210124, + 303.799927, + -0.0140510211, + -0.0, + -0.108596757, + 193.948029, + 835.997314, + 308.477295, + -0.0, + -0.0, + -0.223255008, + 0.243111223, + -0.0, + 242.495178, + 259.149445, + -0.0, + 387.832031, + -0.0, + 0.141625866, + -0.179095998, + -0.0, + -0.0, + 130.752228, + 178.550323, + 185.936539, + 138.219543, + 0.00337153976, + 624.396484, + 245.499268, + -0.0, + 135.377991, + 706.138672, + 133.177551, + -0.0, + -0.344449401, + -0.0, + 129.257629, + 160.304306, + 215.135559, + 124.444336, + -0.0, + -0.181022376, + -0.0, + 534.3302, + -0.0244926531, + -0.0, + 102.011719, + -0.205192044, + -0.0, + -0.0, + 0.355336905, + -0.129933119, + -0.0, + -0.0, + 0.166732222, + 148.854065, + -0.0, + 107.57843, + -0.0, + -0.172828451, + -0.0, + 0.287948906, + -0.0, + -0.0, + 0.372195601, + -0.0, + -0.137157276, + 0.00342750759, + 112.859863, + 123.846924, + -0.0, + 0.0692682266, + -0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + -1, + 29, + 31, + 33, + 35, + -1, + 37, + 39, + 41, + 43, + -1, + 45, + 47, + -1, + 49, + 51, + 53, + 55, + -1, + 57, + 59, + 61, + -1, + -1, + -1, + 63, + -1, + -1, + 65, + -1, + -1, + 67, + -1, + 69, + -1, + -1, + 71, + 73, + -1, + 75, + 77, + -1, + 79, + -1, + 81, + 83, + -1, + 85, + 87, + -1, + -1, + -1, + -1, + 89, + -1, + 91, + -1, + -1, + -1, + 93, + -1, + -1, + -1, + 95, + 97, + 99, + -1, + -1, + -1, + -1, + -1, + 101, + 103, + -1, + 105, + -1, + -1, + -1, + -1, + -1, + 107, + 109, + 111, + 113, + -1, + 115, + 117, + -1, + 119, + 121, + 123, + -1, + -1, + -1, + 125, + 127, + 129, + 131, + -1, + -1, + -1, + 133, + -1, + -1, + 135, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 137, + -1, + 139, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 141, + 143, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + -1, + 30, + 32, + 34, + 36, + -1, + 38, + 40, + 42, + 44, + -1, + 46, + 48, + -1, + 50, + 52, + 54, + 56, + -1, + 58, + 60, + 62, + -1, + -1, + -1, + 64, + -1, + -1, + 66, + -1, + -1, + 68, + -1, + 70, + -1, + -1, + 72, + 74, + -1, + 76, + 78, + -1, + 80, + -1, + 82, + 84, + -1, + 86, + 88, + -1, + -1, + -1, + -1, + 90, + -1, + 92, + -1, + -1, + -1, + 94, + -1, + -1, + -1, + 96, + 98, + 100, + -1, + -1, + -1, + -1, + -1, + 102, + 104, + -1, + 106, + -1, + -1, + -1, + -1, + -1, + 108, + 110, + 112, + 114, + -1, + 116, + 118, + -1, + 120, + 122, + 124, + -1, + -1, + -1, + 126, + 128, + 130, + 132, + -1, + -1, + -1, + 134, + -1, + -1, + 136, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 138, + -1, + 140, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 142, + 144, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 2, + 2, + -2, + 0, + 0, + 7, + 7, + 1, + 0, + 6, + 10, + 6, + 6, + 6, + 7, + 8, + -2, + 6, + 7, + 6, + 0, + 0, + 0, + 0, + 7, + 0, + 7, + -2, + 1, + -2, + -2, + 6, + 8, + 0, + -2, + 10, + 9, + 5, + 7, + -2, + -2, + 8, + 0, + 10, + -2, + 8, + 6, + 10, + 10, + -2, + -2, + 6, + -2, + 0, + 8, + 6, + 6, + -2, + -2, + 7, + 0, + -2, + 9, + -2, + 7, + 9, + -2, + 7, + -2, + 8, + -2, + 0, + -2, + 6, + -2, + 5, + -2, + -2, + -2, + 7, + 10, + 0, + -2, + 10, + 5, + 7, + -2, + 7, + -2, + -2, + -2, + 0, + -2, + -2, + 6, + 7, + -2, + 0, + -2, + -2, + 6, + -2, + -2, + -2, + -2, + -2, + 1, + -2, + -2, + -2, + -2, + 0, + 0, + 9, + -2, + -2, + -2, + -2, + 5, + 9, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 2, + -2, + -2, + 10, + -2, + -2, + 2, + 6, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 0, + -2, + -2, + 0, + 10, + -2, + -2, + -2, + -2, + 7, + -2, + 0, + -2, + -2, + -2, + -2, + 7, + -2, + 6, + -2, + -2, + -2 + ], + "threshold": [ + 0.96875, + -0.9375, + 0.0, + 0.484375, + 0.390625, + -0.7578125, + -0.78125, + -0.15625, + 0.8203125, + -0.875, + -0.3125, + -0.984375, + -0.8828125, + -0.90625, + -0.9296875, + -0.875, + 0.0, + -0.96875, + -0.7734375, + -0.8984375, + -0.078125, + 0.953125, + 0.8125, + 0.9296875, + 0.2109375, + -0.984375, + -0.8671875, + 0.0, + 0.90625, + 0.0, + 0.0, + -0.984375, + -0.75, + 0.09375, + 0.0, + -0.53125, + -0.75, + -0.875, + -0.2109375, + 0.0, + 0.0, + -0.5, + 0.890625, + -0.125, + 0.0, + -0.625, + -0.59375, + -0.90625, + -0.34375, + 0.0, + 0.0, + -0.765625, + 0.0, + -0.7890625, + -0.75, + -0.953125, + -0.9453125, + 0.0, + 0.0, + -0.5, + 0.0703125, + 0.0, + 0.5, + 0.0, + -0.375, + -0.5, + 0.0, + -0.8203125, + 0.0, + -0.75, + 0.0, + 0.6015625, + 0.0, + -0.8671875, + 0.0, + -0.875, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.21875, + -0.625, + 0.0, + -0.90625, + -0.875, + -0.9296875, + 0.0, + -0.8671875, + 0.0, + 0.0, + 0.0, + -0.4140625, + 0.0, + 0.0, + -0.984375, + -0.734375, + 0.0, + -0.4765625, + 0.0, + 0.0, + -0.9765625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.96875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8515625, + -0.90625, + -0.25, + 0.0, + 0.0, + 0.0, + 0.0, + 0.5, + -0.25, + 0.0, + 0.0, + 0.0, + 0.3828125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.96875, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0, + -0.90625, + -0.9765625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.8359375, + 0.0, + 0.0, + 0.0, + -0.9609375, + 0.0, + 0.0, + -0.8203125, + -0.28125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.984375, + 0.0, + -0.0546875, + 0.0, + 0.0, + 0.0, + 0.0, + -0.734375, + 0.0, + -0.921875, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 709.052185, + 715.017395, + 0.206118122, + 779.154541, + 1828.01404, + 268.130432, + 1516.81934, + 312.635437, + 588.300537, + 376.019196, + 176.13623, + 837.602783, + 795.544556, + 528.330688, + 969.345886, + 248.700928, + -0.0, + 291.097687, + 145.836914, + 556.378601, + 204.052658, + 305.845947, + 658.255249, + 411.928528, + 275.839264, + 119.231453, + 629.112183, + -0.0, + 565.435181, + -0.0, + -0.368131191, + 745.109009, + 833.866699, + 104.674194, + -0.0, + 123.022026, + 160.552063, + 314.799438, + 355.266968, + 0.27947861, + -0.0, + 345.377014, + 263.897125, + 472.410522, + -0.0, + 263.723145, + 134.191406, + 276.234161, + 187.796982, + -0.0, + 0.141155586, + 600.098389, + -0.0, + 322.030273, + 230.87262, + 470.709595, + 320.023193, + -0.258159757, + -0.0, + 310.638123, + 571.618774, + -0.0, + 215.066162, + -0.0, + 292.206726, + 400.677094, + -0.0, + 228.073486, + -0.0, + 182.630463, + -0.0, + 239.163208, + -0.0, + 387.70575, + -0.0, + 233.12323, + 0.0873955339, + -0.0, + -0.130965009, + 423.640381, + 359.591553, + 200.125, + -0.0, + 591.770081, + 180.250137, + 263.370239, + -0.0, + 534.529297, + -0.0, + -0.126456246, + -0.0, + 373.838654, + -0.0, + -0.0, + 172.713928, + 172.273071, + -0.0, + 116.421204, + -0.0, + -0.0, + 218.251526, + 0.336897701, + -0.0, + -0.227704987, + -0.0, + -0.0, + 157.131226, + -0.0, + 0.354756415, + -0.0, + -0.232665062, + 758.701416, + 372.134003, + 303.101318, + -0.0, + -0.0, + -0.320690274, + -0.0, + 290.102417, + 253.896469, + -0.0, + -0.0, + -0.225790814, + 305.668579, + -0.0, + -0.0, + -0.240162104, + 0.453615934, + -0.0, + -0.0, + 0.223512679, + -0.0, + 0.187484264, + -0.0, + 133.832397, + -0.238833055, + -0.0, + 127.163467, + 0.215425238, + -0.0, + 244.286804, + 338.876953, + -0.0, + -0.191547945, + -0.0, + 0.0833721161, + -0.0, + 212.000732, + -0.0, + -0.0, + -0.272891045, + 106.375099, + 0.0116562927, + -0.0, + 202.626221, + 240.75708, + -0.0, + -0.0, + 0.368378609, + -0.0, + 329.265625, + -0.0, + 177.163086, + -0.0, + 0.243755952, + -0.0, + -0.231619403, + 111.290894, + -0.0, + 142.220337, + -0.0, + -0.162458405, + -0.0 + ], + "children_left": [ + 1, + 3, + -1, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + -1, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + -1, + 51, + -1, + -1, + 53, + 55, + 57, + -1, + 59, + 61, + 63, + 65, + -1, + -1, + 67, + 69, + 71, + -1, + 73, + 75, + 77, + 79, + -1, + -1, + 81, + -1, + 83, + 85, + 87, + 89, + -1, + -1, + 91, + 93, + -1, + 95, + -1, + 97, + 99, + -1, + 101, + -1, + 103, + -1, + 105, + -1, + 107, + -1, + 109, + -1, + -1, + -1, + 111, + 113, + 115, + -1, + 117, + 119, + 121, + -1, + 123, + -1, + -1, + -1, + 125, + -1, + -1, + 127, + 129, + -1, + 131, + -1, + -1, + 133, + -1, + -1, + -1, + -1, + -1, + 135, + -1, + -1, + -1, + -1, + 137, + 139, + 141, + -1, + -1, + -1, + -1, + 143, + 145, + -1, + -1, + -1, + 147, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 149, + -1, + -1, + 151, + -1, + -1, + 153, + 155, + -1, + -1, + -1, + -1, + -1, + 157, + -1, + -1, + -1, + 159, + -1, + -1, + 161, + 163, + -1, + -1, + -1, + -1, + 165, + -1, + 167, + -1, + -1, + -1, + -1, + 169, + -1, + 171, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + -1, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + -1, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + -1, + 52, + -1, + -1, + 54, + 56, + 58, + -1, + 60, + 62, + 64, + 66, + -1, + -1, + 68, + 70, + 72, + -1, + 74, + 76, + 78, + 80, + -1, + -1, + 82, + -1, + 84, + 86, + 88, + 90, + -1, + -1, + 92, + 94, + -1, + 96, + -1, + 98, + 100, + -1, + 102, + -1, + 104, + -1, + 106, + -1, + 108, + -1, + 110, + -1, + -1, + -1, + 112, + 114, + 116, + -1, + 118, + 120, + 122, + -1, + 124, + -1, + -1, + -1, + 126, + -1, + -1, + 128, + 130, + -1, + 132, + -1, + -1, + 134, + -1, + -1, + -1, + -1, + -1, + 136, + -1, + -1, + -1, + -1, + 138, + 140, + 142, + -1, + -1, + -1, + -1, + 144, + 146, + -1, + -1, + -1, + 148, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 150, + -1, + -1, + 152, + -1, + -1, + 154, + 156, + -1, + -1, + -1, + -1, + -1, + 158, + -1, + -1, + -1, + 160, + -1, + -1, + 162, + 164, + -1, + -1, + -1, + -1, + 166, + -1, + 168, + -1, + -1, + -1, + -1, + 170, + -1, + 172, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 5, + 7, + 10, + 8, + 9, + 10, + -2, + 6, + 0, + 10, + -2, + 7, + 9, + 7, + 3, + 0, + 6, + -2, + -2, + 5, + 1, + 0, + -2, + 10, + 0, + 9, + -2, + 7, + -2, + -2, + 1, + 7, + 7, + -2, + 0, + 9, + 7, + 0, + 6, + 10, + 9, + -2, + -2, + -2, + -2, + 7, + -2, + -2, + -2, + 0, + 7, + -2, + -2, + 7, + -2, + -2, + 9, + -2, + 6, + 2, + -2, + 1, + 1, + -2, + 7, + 0, + -2, + -2, + 6, + 0, + -2, + 0, + -2, + -2, + 10, + 10, + 6, + -2, + -2, + 2, + -2, + 6, + -2, + -2, + 0, + 9, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 10, + -2, + -2, + -2, + 6, + -2, + 9, + -2, + 7, + -2, + 7, + -2, + 2, + -2, + -2, + 8, + 7, + -2, + -2, + 5, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 10, + -2, + -2, + -2, + 0, + -2, + -2, + 7, + -2, + -2 + ], + "threshold": [ + 0.25, + -0.109375, + 0.15625, + -0.75, + 0.25, + -0.8125, + 0.0, + -0.8828125, + -0.2890625, + 0.84375, + 0.0, + -0.84375, + 0.25, + -0.921875, + 0.0, + -0.4140625, + -0.984375, + 0.0, + 0.0, + 0.625, + -0.59375, + 0.203125, + 0.0, + -0.5625, + -0.3828125, + -0.5, + 0.0, + -0.9453125, + 0.0, + 0.0, + 0.96875, + -0.8671875, + -0.9296875, + 0.0, + 0.4765625, + 0.0, + -0.890625, + -0.234375, + -0.96875, + -0.375, + -0.5, + 0.0, + 0.0, + 0.0, + 0.0, + -0.21875, + 0.0, + 0.0, + 0.0, + -0.875, + -0.90625, + 0.0, + 0.0, + -0.71875, + 0.0, + 0.0, + -0.75, + 0.0, + -0.9921875, + 0.96875, + 0.0, + 0.78125, + -0.59375, + 0.0, + -0.890625, + 0.921875, + 0.0, + 0.0, + -0.9765625, + -0.4296875, + 0.0, + 0.125, + 0.0, + 0.0, + -0.28125, + -0.84375, + -0.9765625, + 0.0, + 0.0, + -0.65625, + 0.0, + -0.90625, + 0.0, + 0.0, + 0.8125, + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.8125, + 0.0, + -0.96875, + 0.0, + 0.0, + 0.0, + -0.953125, + 0.0, + -0.75, + 0.0, + -0.4296875, + 0.0, + -0.2890625, + 0.0, + -0.9375, + 0.0, + 0.0, + -0.875, + -0.7421875, + 0.0, + 0.0, + -0.375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.6171875, + 0.0, + 0.0, + 0.0, + 0.984375, + 0.0, + 0.0, + 0.0, + -0.7890625, + 0.0, + 0.0, + -0.875, + 0.0, + 0.0 + ], + "value": [ + 622.320374, + 597.315796, + 648.964722, + 576.234985, + 310.083679, + 564.521362, + -0.089825891, + 450.797668, + 1102.3905, + 373.098816, + -0.0, + 260.601624, + 380.330322, + 519.789124, + 886.817627, + 383.25177, + 526.681885, + 0.163223282, + -0.0, + 196.181244, + 559.992188, + 423.792847, + -0.0, + 332.409393, + 456.001892, + 376.86145, + -0.0, + 234.190689, + 0.14907214, + -0.0, + 199.073975, + 244.803833, + 139.008362, + -0.0, + 182.314209, + 155.857635, + 433.891602, + 168.228882, + 194.266617, + 409.100983, + 699.609741, + -0.0, + 0.318947941, + -0.117794693, + -0.0, + 260.861328, + -0.0, + 0.0720388442, + -0.0, + 166.631302, + 275.184509, + -0.390388608, + -0.0, + 123.417114, + -0.0, + -0.0, + 632.800537, + -0.0, + 508.17746, + 223.037659, + -0.0, + 167.505707, + 101.993736, + -0.0, + 558.323608, + 167.721191, + -0.0, + -0.0, + 263.271332, + 224.243591, + -0.0, + 184.761749, + -0.0, + -0.0, + 633.100098, + 289.994446, + 155.849167, + -0.112882651, + -0.0, + 154.791809, + -0.0, + 197.369324, + -0.0, + -0.0, + 197.903809, + 146.946533, + -0.0, + -0.12342108, + -0.0, + -0.0, + 0.148086593, + 0.083515048, + -0.0, + 538.805176, + -0.0, + 149.014771, + -0.0, + -0.132212982, + -0.0, + 166.045105, + -0.0, + 248.701691, + -0.0, + 316.404541, + -0.0, + 128.107422, + -0.0, + 1282.49268, + -0.0, + -0.0, + 224.277954, + 268.974121, + -0.0, + -0.0, + 200.925232, + -0.208415687, + -0.0, + -0.219791859, + -0.0, + 0.565376222, + -0.0, + 333.980835, + -0.0, + -0.134864971, + -0.0, + 107.814941, + -0.0, + 0.198313981, + -0.0, + 136.924683, + -0.0, + -0.0, + 288.451416, + -0.0, + 0.200334191 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + -1, + 13, + 15, + 17, + -1, + 19, + 21, + 23, + 25, + 27, + 29, + -1, + -1, + 31, + 33, + 35, + -1, + 37, + 39, + 41, + -1, + 43, + -1, + -1, + 45, + 47, + 49, + -1, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + -1, + -1, + -1, + -1, + 65, + -1, + -1, + -1, + 67, + 69, + -1, + -1, + 71, + -1, + -1, + 73, + -1, + 75, + 77, + -1, + 79, + 81, + -1, + 83, + 85, + -1, + -1, + 87, + 89, + -1, + 91, + -1, + -1, + 93, + 95, + 97, + -1, + -1, + 99, + -1, + 101, + -1, + -1, + 103, + 105, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 107, + -1, + 109, + -1, + -1, + -1, + 111, + -1, + 113, + -1, + 115, + -1, + 117, + -1, + 119, + -1, + -1, + 121, + 123, + -1, + -1, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + 127, + -1, + -1, + -1, + 129, + -1, + -1, + -1, + 131, + -1, + -1, + 133, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + -1, + 14, + 16, + 18, + -1, + 20, + 22, + 24, + 26, + 28, + 30, + -1, + -1, + 32, + 34, + 36, + -1, + 38, + 40, + 42, + -1, + 44, + -1, + -1, + 46, + 48, + 50, + -1, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + -1, + -1, + -1, + -1, + 66, + -1, + -1, + -1, + 68, + 70, + -1, + -1, + 72, + -1, + -1, + 74, + -1, + 76, + 78, + -1, + 80, + 82, + -1, + 84, + 86, + -1, + -1, + 88, + 90, + -1, + 92, + -1, + -1, + 94, + 96, + 98, + -1, + -1, + 100, + -1, + 102, + -1, + -1, + 104, + 106, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 108, + -1, + 110, + -1, + -1, + -1, + 112, + -1, + 114, + -1, + 116, + -1, + 118, + -1, + 120, + -1, + -1, + 122, + 124, + -1, + -1, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + 128, + -1, + -1, + -1, + 130, + -1, + -1, + -1, + 132, + -1, + -1, + 134, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 6, + 0, + 10, + 7, + 5, + 2, + 3, + -2, + 10, + 0, + -2, + 6, + 7, + 0, + -2, + -2, + 10, + 0, + -2, + -2, + -2, + 0, + -2, + -2, + 8, + 0, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 5, + -2, + 1, + -2, + 10, + 0, + -2, + 10, + 8, + 6, + -2, + -2, + -2, + 8, + 9, + 7, + 5, + 7, + -2, + -2, + 7, + 1, + -2, + 7, + 2, + 0, + 0, + 6, + 0, + 0, + 0, + 0, + 9, + -2, + 10, + -2, + -2, + 5, + 2, + 5, + 6, + 7, + -2, + -2, + -2, + 5, + -2, + 5, + -2, + 0, + 7, + -2, + -2, + 7, + -2, + -2, + 6, + 0, + 0, + -2, + -2, + 10, + 6, + 6, + -2, + 5, + 0, + -2, + -2, + -2, + -2, + 9, + -2, + -2, + -2, + -2, + 2, + 1, + 7, + -2, + 7, + -2, + 2, + 7, + 2, + 6, + 0, + 5, + -2, + -2, + -2, + -2, + 5, + -2, + 6, + -2, + -2, + 6, + -2, + 7, + 0, + -2, + 2, + -2, + -2, + -2, + 10, + -2, + -2, + 7, + -2, + 6, + 6, + -2, + 7, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + 0, + -2, + -2, + -2, + -2, + -2, + 0, + -2, + 9, + -2, + -2, + -2, + -2, + 0, + -2, + -2 + ], + "threshold": [ + 0.796875, + 0.6484375, + -0.984375, + 0.484375, + -0.9375, + -0.7578125, + -0.125, + 0.96875, + 0.0, + 0.0, + 0.4375, + 0.953125, + 0.0, + -0.859375, + -0.8984375, + 0.3828125, + 0.0, + 0.0, + -0.34375, + 0.671875, + 0.0, + 0.0, + 0.0, + 0.84375, + 0.0, + 0.0, + -0.5, + 0.375, + -0.1484375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.875, + 0.0, + -0.59375, + 0.0, + -0.90625, + -0.53125, + 0.0, + -0.9375, + -0.75, + -0.9921875, + 0.0, + 0.0, + 0.0, + -0.875, + -0.5, + -0.953125, + -0.875, + -0.75, + 0.0, + 0.0, + -0.9609375, + 0.21875, + 0.0, + -0.875, + -0.65625, + -0.9296875, + -0.5625, + -0.890625, + -0.3359375, + -0.8203125, + -0.875, + -0.0703125, + 0.0, + 0.0, + -0.5, + 0.0, + 0.0, + -0.25, + -0.90625, + 0.75, + -0.96875, + -0.5078125, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.625, + 0.0, + 0.3125, + -0.9453125, + 0.0, + 0.0, + -0.1328125, + 0.0, + 0.0, + -0.875, + -0.8828125, + 0.2734375, + 0.0, + 0.0, + 0.875, + -0.7734375, + -0.7734375, + 0.0, + 0.0, + 0.328125, + 0.0, + 0.0, + 0.0, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + -0.25, + 0.78125, + -0.9609375, + 0.0, + -0.734375, + 0.0, + -0.875, + -0.578125, + -0.96875, + -0.3515625, + -0.34375, + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + -0.125, + 0.0, + -0.6328125, + 0.0, + 0.0, + -0.8046875, + 0.0, + -0.453125, + 0.265625, + 0.0, + -0.84375, + 0.0, + 0.0, + 0.0, + 0.1875, + 0.0, + 0.0, + -0.8828125, + 0.0, + -0.9765625, + -0.9765625, + 0.0, + -0.96875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.2734375, + 0.0, + 0.0, + 0.0, + 0.28125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.359375, + 0.0, + -0.75, + 0.0, + 0.0, + 0.0, + 0.0, + -0.6796875, + 0.0, + 0.0 + ], + "value": [ + 314.786621, + 723.988525, + 489.644226, + 294.724304, + 472.870605, + 686.233337, + 292.837982, + 221.908569, + 711.675354, + -0.0, + 350.452759, + 507.588989, + -0.0, + 507.034302, + 478.87207, + 128.455002, + 0.121266484, + -0.0, + 815.274902, + 175.173096, + -0.0, + 0.354303956, + -0.0, + 110.63501, + -0.0, + -0.0, + 360.456238, + 595.797058, + 143.954102, + 0.277920604, + -0.0, + -0.0, + -0.199909598, + -0.0, + -0.205318421, + 0.292527616, + -0.0, + 306.086487, + 0.242700845, + 103.888916, + -0.0, + 198.360657, + 255.051575, + -0.0, + 270.398132, + 308.492584, + 295.119537, + -0.0, + 0.181456611, + -0.0, + 101.493286, + 443.915619, + 473.115326, + 173.402817, + 679.546509, + -0.0, + -0.214814201, + 399.475189, + 154.500916, + -0.0, + 617.503479, + 194.49939, + 169.171616, + 1323.83838, + 168.085358, + 508.763123, + 282.539032, + 134.448486, + 118.233452, + 193.748901, + -0.0, + 214.364166, + -0.0, + -0.0, + 210.030426, + 172.632904, + 414.744629, + 255.74585, + 463.661407, + -0.171743602, + -0.0, + 0.0307323188, + 156.394562, + -0.0, + 131.78772, + -0.0, + 311.395874, + 234.411499, + -0.0, + -0.0, + 221.835358, + 0.0757466182, + -0.0, + 208.78479, + 305.94281, + 392.458984, + -0.0, + -0.0, + 180.112518, + 1247.16309, + 687.151245, + -0.0, + 245.047119, + 148.220093, + -0.0, + -0.160699263, + -0.0, + -0.0, + 103.818848, + -0.10041818, + -0.0, + 0.0602581725, + -0.0, + 163.907059, + 301.531982, + 286.125977, + -0.0, + 184.308075, + -0.0, + 252.349121, + 268.830933, + 384.46228, + 200.14267, + 319.361328, + 119.53154, + 0.0743828118, + -0.0, + -0.0, + 0.272493929, + 313.043152, + -0.10213843, + 327.186462, + -0.0, + -0.0, + 107.502686, + -0.0, + 127.871338, + 106.327881, + -0.0, + 616.715393, + -0.0, + -0.0, + -0.279510766, + 312.787109, + -0.0, + -0.0, + 129.060486, + 0.0305084344, + 150.104752, + 121.297943, + -0.0, + 172.29248, + -0.0, + -0.22026071, + -0.0, + -0.169224441, + -0.0, + 0.215341672, + -0.0, + -0.280555099, + -0.0, + 322.816589, + -0.0, + -0.206693113, + -0.0, + 161.624222, + -0.0, + -0.0, + 0.138241738, + -0.0, + -0.158602387, + 100.57843, + -0.0, + 121.801086, + -0.0, + -0.0, + 0.241289884, + -0.0, + 150.909729, + -0.0, + -0.173824638 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + -1, + 19, + 21, + -1, + 23, + 25, + 27, + -1, + -1, + 29, + 31, + -1, + -1, + -1, + 33, + -1, + -1, + 35, + 37, + 39, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 41, + -1, + 43, + -1, + 45, + 47, + -1, + 49, + 51, + 53, + -1, + -1, + -1, + 55, + 57, + 59, + 61, + 63, + -1, + -1, + 65, + 67, + -1, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + -1, + 89, + -1, + -1, + 91, + 93, + 95, + 97, + 99, + -1, + -1, + -1, + 101, + -1, + 103, + -1, + 105, + 107, + -1, + -1, + 109, + -1, + -1, + 111, + 113, + 115, + -1, + -1, + 117, + 119, + 121, + -1, + 123, + 125, + -1, + -1, + -1, + -1, + 127, + -1, + -1, + -1, + -1, + 129, + 131, + 133, + -1, + 135, + -1, + 137, + 139, + 141, + 143, + 145, + 147, + -1, + -1, + -1, + -1, + 149, + -1, + 151, + -1, + -1, + 153, + -1, + 155, + 157, + -1, + 159, + -1, + -1, + -1, + 161, + -1, + -1, + 163, + -1, + 165, + 167, + -1, + 169, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 171, + -1, + -1, + -1, + 173, + -1, + -1, + -1, + -1, + -1, + 175, + -1, + 177, + -1, + -1, + -1, + -1, + 179, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + -1, + 20, + 22, + -1, + 24, + 26, + 28, + -1, + -1, + 30, + 32, + -1, + -1, + -1, + 34, + -1, + -1, + 36, + 38, + 40, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 42, + -1, + 44, + -1, + 46, + 48, + -1, + 50, + 52, + 54, + -1, + -1, + -1, + 56, + 58, + 60, + 62, + 64, + -1, + -1, + 66, + 68, + -1, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + -1, + 90, + -1, + -1, + 92, + 94, + 96, + 98, + 100, + -1, + -1, + -1, + 102, + -1, + 104, + -1, + 106, + 108, + -1, + -1, + 110, + -1, + -1, + 112, + 114, + 116, + -1, + -1, + 118, + 120, + 122, + -1, + 124, + 126, + -1, + -1, + -1, + -1, + 128, + -1, + -1, + -1, + -1, + 130, + 132, + 134, + -1, + 136, + -1, + 138, + 140, + 142, + 144, + 146, + 148, + -1, + -1, + -1, + -1, + 150, + -1, + 152, + -1, + -1, + 154, + -1, + 156, + 158, + -1, + 160, + -1, + -1, + -1, + 162, + -1, + -1, + 164, + -1, + 166, + 168, + -1, + 170, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 172, + -1, + -1, + -1, + 174, + -1, + -1, + -1, + -1, + -1, + 176, + -1, + 178, + -1, + -1, + -1, + -1, + 180, + -1, + -1 + ] + } + ] + ], + "config": { + "output_dir": "/afs/cern.ch/work/p/pviscone/L1T/l1teg-ML/models/EB_TkEleID/xgb_2class/v1/results/q_8/conifer_model_cpp", + "project_name": "my_prj", + "backend": "cpp", + "input_precision": "ap_fixed<8,1,AP_RND_CONV,AP_SAT>", + "threshold_precision": "ap_fixed<8,1,AP_RND_CONV,AP_SAT>", + "score_precision": "ap_fixed<11,4,AP_RND_CONV,AP_SAT>" + }, + "metadata": [ + { + "version": "0.1.dev372+g0344f4d", + "host": "vocms1003.cern.ch", + "user": "pviscone", + "time": 1780065274.755163 + } + ] +} \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py index e55c9530ec6c2..5268f63f17c95 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py @@ -62,14 +62,14 @@ ), #Algorithm 4: compositeEB_v1 cms.PSet( - model=cms.string("L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.json"), + model=cms.string("L1Trigger/Phase2L1ParticleFlow/data/egamma/compositeID_EB_v1.1.json"), loose_wp=cms.PSet( bins=cms.vdouble(0), values=cms.vdouble(-1) ), tight_wp=cms.PSet( - bins=cms.vdouble(0, 5, 10, 30), - values=cms.vdouble(0.17, 0.018, -0.08, -0.11), + bins=cms.vdouble(0, 6, 8, 10, 18, 25, 30), + values=cms.vdouble(0.0766603755105294, 0.06933593749954339, 0.012695312500194183, -0.03613282237932949, -0.0508455714180935, -0.11718749997898464, -0.1699629435703133), ), dPhi_max = cms.double(0.3), dEta_max = cms.double(0.03), diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index 93f79cc72963d..2dfa4a54b7c13 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -382,13 +382,7 @@ id_score_t l1ct::TkEgCID_EB_v1::compute_score(const CompositeCandidate &cand, float cl_pt = calo.floatPt(); //This two ratios will be computed in the calotrigger and passed to the CTL1 in 6 bits float cl_ss = calo.hwShowerShape.to_float(); - - // FIXME: this is a workaround as the training was erronously done with this variable - ap_ufixed<16, 0> calo_invPt = l1ct::invert_with_shift, 1024>(calo.hwPt); - float reliso_hack = calo.hwPt == 1 ? calo.floatRelIso() : calo.floatRelIso() * calo_invPt.to_float(); - - l1ct::rel_iso_t hw_reliso_hack = l1ct::Scales::makeRelIso(reliso_hack); - float cl_relIso = hw_reliso_hack.to_float(); + float cl_relIso = calo.hwRelIso.to_float(); float cl_staWP = calo.hwEmID & 0x1; float cl_looseTkWP = (calo.hwEmID & 0x2) == 0x2; float tk_chi2RPhi = chi2RPhiBins[tk.hwRedChi2RPhi.to_int()]; From 876f362f4ceb57e738be389674442a991cad83e6 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 5 Jun 2026 14:44:43 +0200 Subject: [PATCH 76/92] Foton WP now matches the suggestion of using looseTk WP. --- L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index a96e959db46f4..47cec7d51a244 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1061,7 +1061,7 @@ namespace p2eg { inline int standaloneWP() const { return (is_iso && is_ss); } inline int looseL1TkMatchWP() const { return (is_looseTkiso && is_looseTkss); } - inline int photonWP() const { return 1; } // NOTE: NO PHOTON WP + inline int photonWP() const { return (is_looseTkiso && is_looseTkss); } // NOTE: NO PHOTON WP inline int passesShowerShape() const { return is_ss; } From 405b103ada9274cb91933c3fcd6ce5797989758b Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 5 Jun 2026 14:48:28 +0200 Subject: [PATCH 77/92] Fix em pt for calibration --- .../src/l1-converters/gcthadinput_ref.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index 819b52bf64c6e..117f2e3f3ec42 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -37,8 +37,8 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame if (corrector_.valid()) { - float newpt = - corrector_.correctedPt(calo.floatPt(), calo.floatPt(), calo.floatEta()); // NOTE: this is still abs(globalEta) + float newpt = corrector_.correctedPt( + calo.floatPt(), calo.floatEmPt(), calo.floatEta()); // NOTE: this is still abs(globalEta) calo.hwPt = l1ct::Scales::makePtFromFloat(newpt); } From 7c8b2c9a858a9bb82516fb9394a05e6c02f79e51 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 5 Jun 2026 14:49:09 +0200 Subject: [PATCH 78/92] Make constant static --- .../src/regionizer/middle_buffer_multififo_regionizer_ref.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp index be15dcaffe78a..d82d2ee9353c0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/middle_buffer_multififo_regionizer_ref.cpp @@ -489,8 +489,8 @@ void l1ct::MiddleBufferMultififoRegionizerEmulator::fillSharedCaloLinks( const unsigned int NEM_WORDS = 16; const unsigned int NHAD_WORDS = 24; - const std::vector gct_slr_tmux18sector_mapping = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2}; - const std::vector slr_order_per_link = {7, 1, 6, 0}; + static constexpr unsigned int gct_slr_tmux18sector_mapping[12] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2}; + static constexpr unsigned int slr_order_per_link[4] = {7, 1, 6, 0}; for (unsigned int is = 0; is < NCALO_SECTORS; ++is) { links[is].clear(); From bb87eb3e6819ec9c8e362c34ea30890bf88a97c5 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Fri, 5 Jun 2026 14:49:36 +0200 Subject: [PATCH 79/92] Cleanup uneeded headers and includes --- .../interface/Phase2L1CaloToCorrelatorTM18.h | 45 ------------------- .../plugins/Phase2L1CaloToCorrelatorTM18.cc | 17 +++---- 2 files changed, 6 insertions(+), 56 deletions(-) delete mode 100644 L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h deleted file mode 100644 index 84575d283d967..0000000000000 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef Phase2L1CaloToCorrelatorTM18_H -#define Phase2L1CaloToCorrelatorTM18_H - -// system include files -#include -#include - -#include -#include -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -//#include "FWCore/Framework/interface/EDAnalyzer.h" -#include "FWCore/Framework/interface/one/EDAnalyzer.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ServiceRegistry/interface/Service.h" - -#include "CommonTools/UtilAlgos/interface/TFileService.h" - -#include -#include -#include -#include -#include - -#include "FWCore/Framework/interface/ESHandle.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedCaloToCorrelatorTM18.h" - -// -// class declaration -// - -#endif diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc index 0f01e5090c4a5..0ad9fba4d37ba 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloToCorrelatorTM18.cc @@ -2,24 +2,19 @@ // system include files #include -#include -#include -#include -#include -#include + #include -#include +#include // user include files #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - -#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloToCorrelatorTM18.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" From 8641895403e24819c03bfff76829cfb987b30a99 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 5 Jun 2026 12:50:50 -0500 Subject: [PATCH 80/92] add missing CMS Exception header to TDR regionizer elements --- .../interface/regionizer/tdr_regionizer_elements_ref.icc | 1 + 1 file changed, 1 insertion(+) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index ed5bcef5ee56f..45f84761c2248 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -2,6 +2,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" // BUFFER ENTRY AND BUFFER template From 44b23caff9c45ffcf5ea5ae19f807977492a80b5 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 5 Jun 2026 12:52:16 -0500 Subject: [PATCH 81/92] automatic scram code-format checks --- .../interface/Phase2L1CaloEGammaUtils.h | 12 ++++++----- .../plugins/Phase2L1CaloPFClusterEmulator.cc | 8 +++++++- .../Phase2L1TCaloBarrelToCorrelator.cc | 20 +++++++++---------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 47cec7d51a244..5d6616c0ac4e4 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -1309,15 +1309,17 @@ namespace p2eg { spare = spare | 1; } - ap_uint<6> shape = (64 * et2x5 / et5x5) + 0.5f ; // normalize to 0x3F + ap_uint<6> shape = (64 * et2x5 / et5x5) + 0.5f; // normalize to 0x3F ap_uint<3> quality = (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); // normalize relIso to 0x3F - float reliso_f = isoFloat() * 4.0f / etFloat() ; // LSB = 16/64 to compress the useful range (0-16) in 6 bits + float reliso_f = isoFloat() * 4.0f / etFloat(); // LSB = 16/64 to compress the useful range (0-16) in 6 bits // implement saturation - if (reliso_f < 0.0f) reliso_f = 0.0f; - if (reliso_f > 63.0f) reliso_f = 63.0f; + if (reliso_f < 0.0f) + reliso_f = 0.0f; + if (reliso_f > 63.0f) + reliso_f = 63.0f; // normalize hoe to 0x3F int hoe_int = (int)(hoe * 63 / 15); @@ -1327,7 +1329,7 @@ namespace p2eg { abseta, phivscenter, ap_uint<6>(hoe_int & 0x3F), - ap_uint<6>(reliso_f + 0.5f), // rounding + ap_uint<6>(reliso_f + 0.5f), // rounding ap_uint<6>(shape), ap_uint<3>(quality), ap_uint<5>(timing), diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc index 70fce6e2c7447..fd9b1be94c564 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloPFClusterEmulator.cc @@ -171,7 +171,13 @@ void Phase2L1CaloPFClusterEmulator::produce(edm::Event& iEvent, const edm::Event float towereta = realEta[gcteta][gctphi]; float towerphi = realPhi[gcteta][gctphi]; reco::Particle::PolarLorentzVector clusterP4(tempPfclusters.GCTpfclusters[i].et, towereta, towerphi, 0); - l1tp2::CaloPFCluster l1CaloPFCluster(clusterP4, tempPfclusters.GCTpfclusters[i].et, tempPfclusters.GCTpfclusters[i].ecal, gcteta, gctphi, towereta, towerphi); + l1tp2::CaloPFCluster l1CaloPFCluster(clusterP4, + tempPfclusters.GCTpfclusters[i].et, + tempPfclusters.GCTpfclusters[i].ecal, + gcteta, + gctphi, + towereta, + towerphi); pfclusterCands->push_back(l1CaloPFCluster); } } diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc index b577f9182047f..bdc5cb53ab171 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -240,7 +240,7 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E // Repeat for PF Clusters for (size_t iCluster = 0; iCluster < inputPFClusters->size(); ++iCluster) { - const l1tp2::CaloPFCluster & pfIn = inputPFClusters->at(iCluster); + const l1tp2::CaloPFCluster& pfIn = inputPFClusters->at(iCluster); // Skip zero-energy clusters if (pfIn.clusterEt() == 0) @@ -266,20 +266,20 @@ void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::E if (iEta > maxEta) { continue; } - ap_uint<7> pf_eta = (ap_uint<7>)((std::abs(pfIn.clusterEta())/ eta_LSB)); - // std::cout << "[GCT] PF Cluster: eta in =" << pfIn.clusterEta() + ap_uint<7> pf_eta = (ap_uint<7>)((std::abs(pfIn.clusterEta()) / eta_LSB)); + // std::cout << "[GCT] PF Cluster: eta in =" << pfIn.clusterEta() // << " abs: " << std::abs(pfIn.clusterEta()) // << " ratio: " << std::abs(pfIn.clusterEta())/ eta_LSB // << " floor: " << std::floor(std::abs(pfIn.clusterEta())/ eta_LSB) // << " rounded: " << std::floor(( std::abs(pfIn.clusterEta())/ eta_LSB) + 0.5) - // << ", eta out=" << pf_eta.to_int() - // << " float: " << pf_eta * eta_LSB - // << " ieta: " << iEta - // << " (f) " << iEta * eta_LSB - // << " LSB: " << eta_LSB - // << " diff: " << std::abs(std::abs(pfIn.clusterEta()) - (pf_eta * eta_LSB))/ eta_LSB + // << ", eta out=" << pf_eta.to_int() + // << " float: " << pf_eta * eta_LSB + // << " ieta: " << iEta + // << " (f) " << iEta * eta_LSB + // << " LSB: " << eta_LSB + // << " diff: " << std::abs(std::abs(pfIn.clusterEta()) - (pf_eta * eta_LSB))/ eta_LSB // << std::endl; - + ap_int<7> pf_phi = 0x7F & int(std::floor(phiDifference)); // greatest integer <= x // Initialize the new cluster From 32c6722d31dbacfb110ce01a9369160a3604d7d1 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 5 Jun 2026 17:24:15 -0500 Subject: [PATCH 82/92] update comments to be correct, remove unneeded include --- .../interface/regionizer/tdr_regionizer_elements_ref.h | 2 +- .../interface/regionizer/tdr_regionizer_elements_ref.icc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index 7787043efa24d..0efcbe084ca33 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -50,7 +50,7 @@ namespace l1ct { Buffer() {} void addEntry(const T& obj, - std::vector srs, // LOGICAL SRs + std::vector srs, // physical SRs int glbeta, int glbphi); diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc index 45f84761c2248..31035c871756c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -1,7 +1,6 @@ #include #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/Exception.h" // BUFFER ENTRY AND BUFFER From 3a4791c73a40f6bf721552b5d27af8fb77a4c0c4 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Mon, 8 Jun 2026 17:59:23 +0200 Subject: [PATCH 83/92] Futher fix for GCT Had calibration --- .../src/l1-converters/gcthadinput_ref.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index 117f2e3f3ec42..77e1d40ec7b3d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -36,15 +36,15 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwEta = l1ct::Scales::makeGlbEta(inclus.eta() * ETA_LSB + ETA_LSB / 2.); // at this point eta is abs(globalEta) calo.hwPhi = l1ct::Scales::makePhi(inclus.phi() * PHI_LSB + (PHI_LSB / 2)); // This is already in the local frame + calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); + + if (corrector_.valid()) { float newpt = corrector_.correctedPt( calo.floatPt(), calo.floatEmPt(), calo.floatEta()); // NOTE: this is still abs(globalEta) calo.hwPt = l1ct::Scales::makePtFromFloat(newpt); } - // need to add EmPt when it becomes available - calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); - // need to add emid, default to zero for had/PF clusters from GCT calo.hwEmID = inclus.fb(); From a2534f6ddcf736364d1020041c3a6ac4f635d3f1 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Tue, 9 Jun 2026 11:35:01 +0200 Subject: [PATCH 84/92] updated with calibration bugfix --- L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 0e22048ba8067..19fff3eeda764 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -56,8 +56,8 @@ gctHadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), gctHadResol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 3.904, 3.240, 1.726), - scale = cms.vdouble( 0.162, 0.221, 0.351), + offset = cms.vdouble( 4.313, 2.665, 1.706), + scale = cms.vdouble( 0.103, 0.158, 0.297), kind = cms.string('calo'), ), ), From 4d2ce58191cd39a72e0a52398bc5a1a5a42a7e98 Mon Sep 17 00:00:00 2001 From: pallabidas Date: Wed, 10 Jun 2026 12:29:33 +0200 Subject: [PATCH 85/92] corrections using pt02 as reference --- .../data/hadcorr_barrel.root | Bin 38170 -> 38052 bytes .../python/l1ctLayer1_cff.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root index 61d1c67595407d577e213beab067ed78ca61572c..ef1e958d1b7eefea5aa272a2807964fde0a067eb 100644 GIT binary patch delta 29859 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 Date: Thu, 11 Jun 2026 16:13:57 +0200 Subject: [PATCH 86/92] tweak tkele EB WP --- .../python/l1TkEgAlgoEmulator_cfi.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py index 5268f63f17c95..99bdad12b509b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py @@ -68,8 +68,20 @@ values=cms.vdouble(-1) ), tight_wp=cms.PSet( - bins=cms.vdouble(0, 6, 8, 10, 18, 25, 30), - values=cms.vdouble(0.0766603755105294, 0.06933593749954339, 0.012695312500194183, -0.03613282237932949, -0.0508455714180935, -0.11718749997898464, -0.1699629435703133), + bins=cms.vdouble(0, + 5.809742647058821, + 9.486213235294112, + 11.32444852941176, + 15.00091911764705, + 28.787683823529395, + 33.38327205882351), + values=cms.vdouble(0.09277362310658768, + -0.016262166169395662, + -0.0732421875, + -0.10888671874999997, + -0.14550773364406097, + -0.20117187500000003, + -0.241983536054637), ), dPhi_max = cms.double(0.3), dEta_max = cms.double(0.03), From f16ec01b2ba49e0443a50823c172575428848d02 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Wed, 17 Jun 2026 16:49:58 +0200 Subject: [PATCH 87/92] rounding to HW values --- .../python/l1TkEgAlgoEmulator_cfi.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py index 99bdad12b509b..855f54116fc34 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py @@ -68,20 +68,8 @@ values=cms.vdouble(-1) ), tight_wp=cms.PSet( - bins=cms.vdouble(0, - 5.809742647058821, - 9.486213235294112, - 11.32444852941176, - 15.00091911764705, - 28.787683823529395, - 33.38327205882351), - values=cms.vdouble(0.09277362310658768, - -0.016262166169395662, - -0.0732421875, - -0.10888671874999997, - -0.14550773364406097, - -0.20117187500000003, - -0.241983536054637), + bins=cms.vdouble(0, 5.75, 9.25, 11.25, 15, 28.75, 33.25), + values=cms.vdouble(0.09375, -0.015625, -0.0742188, -0.109375, -0.144531, -0.201172, -0.242188), ), dPhi_max = cms.double(0.3), dEta_max = cms.double(0.03), From d5857483c35c4cd8b88994ab72f9c750ad1cb36e Mon Sep 17 00:00:00 2001 From: Gianluca Date: Thu, 18 Jun 2026 09:12:42 +0200 Subject: [PATCH 88/92] code-checks --- .../Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp index 77e1d40ec7b3d..e22bfdb217ea1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/gcthadinput_ref.cpp @@ -38,7 +38,6 @@ l1ct::HadCaloObjEmu l1ct::GctHadClusterDecoderEmulator::decode(const l1ct::PFReg calo.hwEmPt = inclus.ecal() * inclus.ptLSB(); - if (corrector_.valid()) { float newpt = corrector_.correctedPt( calo.floatPt(), calo.floatEmPt(), calo.floatEta()); // NOTE: this is still abs(globalEta) From 5800c3de99cde6779cdb22840a8751c650db910c Mon Sep 17 00:00:00 2001 From: Piero Viscone Date: Mon, 23 Jun 2025 13:40:49 +0200 Subject: [PATCH 89/92] Added EM barrel calibs & implementation of the tkele pt regression @ CTL2 --- DataFormats/L1TCorrelator/interface/TkEm.h | 5 +- DataFormats/L1TCorrelator/src/classes_def.xml | 6 +- .../L1TParticleFlow/interface/datatypes.h | 6 + .../L1TParticleFlow/interface/egamma.h | 27 +- .../TkElePtRegr_EB_sigVsBkg_v0_conifer.json | 7831 +++++++++++++++++ .../interface/egamma/l2tkeleregression_ref.h | 70 + .../plugins/L1TCtL2EgProducer.cc | 34 +- .../python/l1ctLayer2EG_cff.py | 6 + .../l1tPFClustersFromL1EGClusters_cfi.py | 3 +- .../src/egamma/l2tkeleregression_ref.cpp | 102 + .../src/egamma/pftkegalgo_ref.cpp | 7 + 11 files changed, 8089 insertions(+), 8 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/data/egamma/TkElePtRegr_EB_sigVsBkg_v0_conifer.json create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp diff --git a/DataFormats/L1TCorrelator/interface/TkEm.h b/DataFormats/L1TCorrelator/interface/TkEm.h index 051a324a8e082..4e3a677632fb2 100644 --- a/DataFormats/L1TCorrelator/interface/TkEm.h +++ b/DataFormats/L1TCorrelator/interface/TkEm.h @@ -56,6 +56,7 @@ namespace l1t { egBinaryWord0_ = word; egBinaryWord1_ = (word >> 32); egBinaryWord2_ = (word >> 64); + egBinaryWord3_ = (word >> 96); encoding_ = encoding; } @@ -68,7 +69,8 @@ namespace l1t { template ap_uint egBinaryWord() const { - return ap_uint(egBinaryWord0_) | (ap_uint(egBinaryWord1_) << 32) | (ap_uint(egBinaryWord2_) << 64); + return ap_uint(egBinaryWord0_) | (ap_uint(egBinaryWord1_) << 32) | (ap_uint(egBinaryWord2_) << 64) | + (ap_uint(egBinaryWord3_) << 96); } HWEncoding encoding() const { return encoding_; } @@ -84,6 +86,7 @@ namespace l1t { uint32_t egBinaryWord0_; uint32_t egBinaryWord1_; uint32_t egBinaryWord2_; + uint32_t egBinaryWord3_; HWEncoding encoding_; }; } // namespace l1t diff --git a/DataFormats/L1TCorrelator/src/classes_def.xml b/DataFormats/L1TCorrelator/src/classes_def.xml index 8ac314ea58ae1..16450c6f0f259 100644 --- a/DataFormats/L1TCorrelator/src/classes_def.xml +++ b/DataFormats/L1TCorrelator/src/classes_def.xml @@ -10,7 +10,8 @@ - + + @@ -51,7 +52,8 @@ - + + diff --git a/DataFormats/L1TParticleFlow/interface/datatypes.h b/DataFormats/L1TParticleFlow/interface/datatypes.h index 88f09a5dcf663..21ad4e360ca16 100644 --- a/DataFormats/L1TParticleFlow/interface/datatypes.h +++ b/DataFormats/L1TParticleFlow/interface/datatypes.h @@ -44,6 +44,7 @@ namespace l1ct { typedef ap_ufixed<11, 9, AP_TRN, AP_SAT> iso_t; typedef ap_ufixed<6, 0, AP_RND, AP_SAT> rel_iso_t; typedef ap_ufixed<6, 0, AP_RND, AP_SAT> shower_shape_t; + typedef ap_ufixed<10, 1, AP_RND, AP_SAT> caloTkPtRatio_t; struct ParticleID { ap_uint<3> bits; @@ -160,6 +161,7 @@ namespace l1ct { constexpr float HOE_LSB = 0.031250000; // pow(2, -5) // empirical choice: we saturate to 16 while waiting for updates to the GCT-CTL1 interface document constexpr unsigned int RELISO_SCALE = 16; + constexpr unsigned int CALOTKPTRATIO_SCALE = 8; inline float floatPt(pt_t pt) { return pt.to_float(); } inline float floatPt(dpt_t pt) { return pt.to_float(); } @@ -190,6 +192,9 @@ namespace l1ct { inline float floatIDProb(id_prob_t prob) { return prob.to_float(); }; inline float floatRelIso(rel_iso_t rel_iso) { return rel_iso.to_float() * RELISO_SCALE; } inline float floatShoweShape(shower_shape_t showe_shape) { return showe_shape.to_float(); } + inline float floatCaloTkPtRatio(caloTkPtRatio_t caloTkPtRatio) { + return caloTkPtRatio.to_float() * CALOTKPTRATIO_SCALE; + } inline pt_t makePt(int pt) { return ap_ufixed<16, 14>(pt) >> 2; } inline dpt_t makeDPt(int dpt) { return ap_fixed<18, 16>(dpt) >> 2; } @@ -225,6 +230,7 @@ namespace l1ct { inline meanz_t makeMeanZ(float var) { return round(var - MEANZ_OFFSET); }; inline hoe_t makeHoe(float var) { return hoe_t(HOE_LSB * round(var / HOE_LSB)); }; inline rel_iso_t makeRelIso(float var) { return rel_iso_t(var / RELISO_SCALE); }; + inline caloTkPtRatio_t makeCaloTkPtRatio(float var) { return caloTkPtRatio_t(var / CALOTKPTRATIO_SCALE); }; inline float maxAbsEta() { return ((1 << (eta_t::width - 1)) - 1) * ETAPHI_LSB; } inline float maxAbsPhi() { return ((1 << (phi_t::width - 1)) - 1) * ETAPHI_LSB; } diff --git a/DataFormats/L1TParticleFlow/interface/egamma.h b/DataFormats/L1TParticleFlow/interface/egamma.h index 3b94ebae565f3..bbb078ffc6033 100644 --- a/DataFormats/L1TParticleFlow/interface/egamma.h +++ b/DataFormats/L1TParticleFlow/interface/egamma.h @@ -90,13 +90,20 @@ namespace l1ct { id_score_t hwIDScore; bool hwCharge; + redChi2Bin_t hwTkRedChi2RPhi; // 4 bits + tkdphi_t hwTkCaloDphi; // 7 bits + shower_shape_t hwCaloShowerShape; // 6 bits + caloTkPtRatio_t hwCaloTkPtRatio; // 10 bits + glbphi_t hwVtxPhi() const { return hwCharge ? hwPhi + hwDPhi : hwPhi - hwDPhi; } glbeta_t hwVtxEta() const { return hwEta + hwDEta; } inline bool operator==(const EGIsoEleObj &other) const { return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwQual == other.hwQual && hwIso == other.hwIso && hwDEta == other.hwDEta && hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && - hwIDScore == other.hwIDScore && hwCharge == other.hwCharge; + hwIDScore == other.hwIDScore && hwCharge == other.hwCharge && hwTkRedChi2RPhi == other.hwTkRedChi2RPhi && + hwTkCaloDphi == other.hwTkCaloDphi && hwCaloShowerShape == other.hwCaloShowerShape && + hwCaloTkPtRatio == other.hwCaloTkPtRatio; } inline bool operator>(const EGIsoEleObj &other) const { return hwPt > other.hwPt; } @@ -113,6 +120,10 @@ namespace l1ct { hwZ0 = 0; hwIDScore = 0; hwCharge = false; + hwTkRedChi2RPhi = 0; + hwTkCaloDphi = 0; + hwCaloShowerShape = 0; + hwCaloTkPtRatio = 0; } int intCharge() const { return hwCharge ? +1 : -1; } @@ -122,9 +133,11 @@ namespace l1ct { float floatVtxPhi() const { return Scales::floatPhi(hwVtxPhi()); } float floatZ0() const { return Scales::floatZ0(hwZ0); } float floatIDScore() const { return Scales::floatIDScore(hwIDScore); } + // FIXME: add accessors - static const int BITWIDTH = - EGIsoObj::BITWIDTH + tkdeta_t::width + tkdphi_t::width + z0_t::width + id_score_t::width + 1; + static const int BITWIDTH = EGIsoObj::BITWIDTH + tkdeta_t::width + tkdphi_t::width + z0_t::width + + id_score_t::width + 1 + redChi2Bin_t::width + tkdphi_t::width + shower_shape_t::width + + caloTkPtRatio_t::width; inline ap_uint pack() const { ap_uint ret; unsigned int start = 0; @@ -138,6 +151,10 @@ namespace l1ct { pack_into_bits(ret, start, hwZ0); pack_bool_into_bits(ret, start, hwCharge); pack_into_bits(ret, start, hwIDScore); + pack_into_bits(ret, start, hwTkRedChi2RPhi); + pack_into_bits(ret, start, hwTkCaloDphi); + pack_into_bits(ret, start, hwCaloShowerShape); + pack_into_bits(ret, start, hwCaloTkPtRatio); return ret; } inline static EGIsoEleObj unpack(const ap_uint &src) { @@ -158,6 +175,10 @@ namespace l1ct { unpack_from_bits(src, start, hwZ0); unpack_bool_from_bits(src, start, hwCharge); unpack_from_bits(src, start, hwIDScore); + unpack_from_bits(src, start, hwTkRedChi2RPhi); + unpack_from_bits(src, start, hwTkCaloDphi); + unpack_from_bits(src, start, hwCaloShowerShape); + unpack_from_bits(src, start, hwCaloTkPtRatio); } l1gt::Electron toGT() const { diff --git a/L1Trigger/Phase2L1ParticleFlow/data/egamma/TkElePtRegr_EB_sigVsBkg_v0_conifer.json b/L1Trigger/Phase2L1ParticleFlow/data/egamma/TkElePtRegr_EB_sigVsBkg_v0_conifer.json new file mode 100644 index 0000000000000..c6a60a434da9e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/data/egamma/TkElePtRegr_EB_sigVsBkg_v0_conifer.json @@ -0,0 +1,7831 @@ +{ + "n_classes": 2, + "n_features": 7, + "n_trees": 12, + "max_depth": 6, + "init_predict": [ + 0 + ], + "norm": 1, + "library": "xgboost", + "splitting_convention": "<", + "feature_map": { + "idScore": 0, + "caloEta": 1, + "caloTkAbsDphi": 2, + "hwTkChi2RPhi": 3, + "caloPt": 4, + "caloSS": 5, + "caloTkPtRatio": 6 + }, + "trees": [ + [ + { + "feature": [ + 0, + 4, + 6, + 0, + 0, + 0, + 3, + 6, + 6, + 0, + 5, + 4, + 4, + 1, + 0, + 0, + 3, + 6, + 3, + 4, + 4, + 1, + 6, + 6, + 1, + 5, + 6, + 6, + 5, + 0, + 4, + 3, + 6, + 2, + 2, + 4, + 3, + 3, + 2, + 0, + 0, + 3, + 6, + 1, + 4, + 4, + 1, + 3, + 4, + 1, + 5, + 6, + 0, + 3, + 6, + 5, + 3, + 6, + 0, + 1, + 6, + 1, + 1, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + -0.0390625, + -0.8125, + -0.876953125, + -0.1875, + -0.1796875, + 0.09375, + 0.0, + -0.8828125, + -0.873046875, + -0.328125, + 0.75, + -0.7265625, + 0.7890625, + 0.0546875, + 0.1796875, + -0.25, + -0.5, + -0.9375, + 0.125, + -0.6953125, + -0.453125, + -0.51953125, + -0.52734375, + -0.9375, + -0.51953125, + 0.96875, + -0.8828125, + -0.29296875, + 0.96875, + 0.0390625, + 0.998046875, + 0.0, + -0.9375, + 0.0, + 0.125, + -0.9140625, + -0.625, + -0.875, + -0.125, + -0.3671875, + -0.390625, + -0.375, + -0.05078125, + -0.572265625, + 0.3046875, + -0.2890625, + 0.38671875, + 0.0, + -0.796875, + -0.572265625, + 0.96875, + -0.90234375, + 0.125, + 0.25, + -0.87890625, + 0.96875, + -0.25, + -0.85546875, + 0.1171875, + 0.0390625, + -0.05078125, + 0.07421875, + 0.109375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5632289.5, + 109191.0, + 1268263.38, + 65421.1562, + 34267.0, + 145327.562, + 642072.438, + 7737.98438, + 36315.4961, + 4299.0, + 20098.125, + 193912.781, + 75344.1875, + 203250.25, + 195513.438, + 5391.49219, + 1702.19531, + 10008.583, + 2994.88867, + 213.0, + 2956.25, + 18963.375, + 8747.0, + 7253.71094, + 44717.9531, + 17400.5625, + 60918.8906, + 100763.0, + 32689.3867, + 30305.5156, + 218790.375, + 1664.14453, + 2475.39014, + 139.226562, + 1393.4209, + 871.678223, + 2856.07422, + 145.373047, + 1463.25024, + 75.609375, + 108.0, + 2519.78125, + 353.625, + 30322.4355, + 2226.5918, + 6356.4375, + 3867.875, + 1631.12988, + 5348.80469, + 30146.7441, + 14324.5469, + 11589.4941, + 8592.3125, + 7925.3125, + 18239.2031, + 83342.5, + 14811.8438, + 2626.97656, + 20414.0898, + 11427.1406, + 25455.4609, + 61355.7344, + 98297.2344, + 0.3046875, + 0.545312524, + 0.915625036, + 0.426562518, + 0.0, + 0.0, + 0.0, + 0.704687536, + 0.904687524, + 0.940625012, + 0.339062512, + 0.412499994, + -0.0687500015, + -0.0578125007, + -0.0375000015, + 0.667187512, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.123437501, + 0.0, + 0.0, + 0.0, + 0.400000006, + 0.0, + -0.00468750019, + 0.090625003, + 0.00312500005, + 0.0, + 0.0515624993, + 0.0, + 1.1953125, + 0.2734375, + 0.184375003, + 0.231250003, + 0.262500018, + 0.0562500022, + 0.275000006, + 0.439062506, + 0.0500000007, + 0.339062512, + 0.0640624985, + 0.082812503, + 0.0234375, + 0.0125000002, + 0.00156250002, + -0.015625, + -0.00937500037, + 0.0, + 0.0421875007, + -0.00937500037, + -0.00625000009, + 0.0281250011, + 0.0, + 0.0296874996, + 0.0515624993, + 0.0421875007, + 0.0640624985, + 0.0109374998, + 0.0359374993, + -0.00625000009, + 0.00937500037 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 4, + 6, + 0, + 0, + 0, + 0, + 6, + 6, + 0, + 5, + 4, + 4, + 6, + 0, + 0, + 3, + 6, + 6, + 0, + 5, + 2, + 4, + 6, + 3, + 6, + 3, + 3, + 3, + 3, + 6, + 6, + 6, + 6, + 6, + 4, + 0, + 6, + 6, + 0, + 4, + 1, + 4, + 5, + 3, + 6, + 5, + 0, + 3, + 1, + 4, + 4, + 0, + 6, + 5, + 6, + 4, + 1, + 0, + 6, + 2, + 6, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.015625, + -0.796875, + -0.884765625, + -0.1875, + -0.0703125, + 0.1171875, + 0.1796875, + -0.90625, + -0.90234375, + -0.2421875, + 0.6875, + -0.859375, + -0.6953125, + 0.50390625, + 0.4765625, + -0.25, + -0.5, + -0.9375, + -0.876953125, + -0.328125, + 0.4375, + -0.75, + -0.6953125, + -0.8984375, + -0.125, + -0.9375, + 0.5, + -0.875, + 0.25, + -0.5, + -0.873046875, + -0.92578125, + -0.9375, + -0.76953125, + -0.8125, + -0.9140625, + -0.0546875, + -0.892578125, + -0.86328125, + -0.390625, + -0.6953125, + -0.51953125, + -0.171875, + 0.5625, + 0.75, + -0.892578125, + 0.75, + 0.109375, + -0.25, + -0.974609375, + -0.796875, + -0.890625, + 0.125, + -0.88671875, + 0.96875, + -0.52734375, + -0.5859375, + 0.3359375, + 0.03125, + -0.396484375, + -0.59375, + -0.876953125, + 0.998046875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5523391.5, + 143185.0, + 228212.578, + 76199.7969, + 67695.0, + 118821.461, + 253697.344, + 5724.39062, + 39009.375, + 15175.0, + 16829.7812, + 42861.0508, + 25797.8906, + 53078.8438, + 108521.906, + 3437.85938, + 1591.0, + 12217.2139, + 4732.22266, + 1542.0, + 5457.75, + 3458.46533, + 5239.0625, + 16560.0332, + 14060.3809, + 5312.71875, + 19817.1172, + 14184.3906, + 6813.75, + 77481.1875, + 63328.4219, + 892.664062, + 1732.44653, + 137.421875, + 749.119141, + 893.491211, + 5370.3125, + 3319.21875, + 1043.31543, + 182.5, + 1420.375, + 11048.3379, + 4554.5, + 1838.48169, + 9.08129883, + 1874.13232, + 3893.6875, + 1517.23438, + 1909.66602, + 9655.57422, + 4457.03174, + 887.305725, + 3067.04688, + 8366.07031, + 8705.48828, + 9659.03906, + 17808.1406, + 2883.51562, + 306.62027, + 27004.4102, + 76575.9375, + 97571.3203, + 46875.4375, + 0.417187512, + 0.146875009, + 0.18312493, + 0.125937462, + 0.0, + 0.0, + 0.0375000015, + 0.0, + 0.176249981, + 0.205312535, + 0.167812541, + 0.200625047, + -0.0265625007, + -0.141562462, + 0.0121874809, + -0.0284375194, + 0.0, + 0.0, + 0.15906249, + 0.0, + 0.375312537, + 0.0, + 0.0131250387, + 0.0, + 0.239999965, + 0.0259374622, + 0.0, + 0.0265625007, + 0.0946874619, + -0.0162500385, + -0.015625, + 0.00906248111, + 0.151562497, + 0.0506250374, + -0.0515624993, + 0.015625, + 0.138437465, + 0.0315625183, + 0.220312506, + 0.106562518, + 1.0440625, + 0.576875031, + 0.105312541, + 0.172187522, + 0.0893750191, + 0.0143750189, + 0.0, + 0.0406250022, + -0.00593748083, + 0.00468750019, + 0.0253125187, + 0.00437498093, + 0.0, + 0.0228124615, + 0.0887499824, + -0.001249981, + -0.00312500005, + 0.00937500037, + 0.00656251935, + 0.0518750213, + -0.00687503815, + 0.00281248102, + -0.00468750019, + 0.0 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 3, + 4, + 1, + 1, + 6, + 6, + 0, + 6, + 6, + 3, + 0, + 1, + 6, + 4, + 3, + 1, + 5, + 1, + 3, + 0, + 4, + 3, + 6, + 6, + 0, + 4, + 4, + 1, + 3, + 0, + 6, + 6, + 5, + 4, + 0, + 4, + 0, + 0, + 4, + 5, + 6, + 4, + 6, + 2, + 0, + 6, + 1, + 4, + 0, + 0, + 4, + 2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.7109375, + -0.89453125, + 0.998046875, + -0.1875, + -0.2421875, + -0.912109375, + 0.0859375, + 0.75, + 0.84375, + -0.640625, + -0.06640625, + -0.912109375, + -0.873046875, + -0.328125, + -0.23046875, + -0.9375, + -0.5, + 0.0078125, + 0.14453125, + -0.908203125, + -0.7109375, + -0.5, + 0.28515625, + 0.96875, + 0.4765625, + 0.0, + 0.3125, + -0.8828125, + -0.5, + -0.912109375, + -0.861328125, + -0.390625, + -0.6875, + 0.359375, + 0.07421875, + -0.125, + -0.0390625, + -0.90625, + -0.908203125, + 0.6875, + 0.8828125, + 0.0859375, + 0.71875, + 0.140625, + 0.1171875, + -0.8359375, + 0.5625, + -0.7265625, + -0.5, + -0.8359375, + -0.75, + 0.4765625, + -0.89453125, + -0.51953125, + -0.1015625, + 0.546875, + 0.4375, + 0.2734375, + -0.09375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5734769.0, + 276219.0, + 104430.617, + 39135.0, + 67725.75, + 76234.75, + 85662.7344, + 27609.6719, + 14132.0, + 27284.5645, + 24929.5, + 13587.7275, + 16087.3594, + 61487.375, + 18529.375, + 2903.6875, + 2149.09082, + 1479.5, + 3997.5, + 8398.24512, + 7510.76172, + 17563.375, + 3368.96875, + 13352.459, + 8418.70703, + 11304.8359, + 16847.125, + 37202.2891, + 41236.3242, + 5926.58594, + 1205.31421, + 1742.50781, + 1482.54688, + 6562.0459, + 1489.04419, + 182.5, + 1170.0, + 3661.625, + 541.25, + 924.049316, + 5589.61719, + 2228.83984, + 1413.93616, + 7000.15625, + 12397.9844, + 2071.0625, + 8063.82715, + 3207.42773, + 13829.9219, + 527.682617, + 1050.44434, + 6866.47656, + 9191.96289, + 10076.1406, + 1303.35425, + 14026.0078, + 10140.1855, + 32158.252, + 5686.28125, + 4163.20312, + 571.233093, + 1139.63342, + 376.542786, + 0.127187535, + -0.015437508, + 0.0, + 0.0, + 0.103874974, + -0.078125, + 0.0190000068, + -0.0269374847, + 0.0, + 0.0, + 0.0164999962, + 0.0, + 0.00531253824, + 0.0, + 0.0, + 0.00625000009, + -0.148250014, + 0.139687538, + 0.0251249317, + 0.186374947, + 0.00287494669, + -0.0396875404, + 0.0521875396, + 0.00249996199, + 0.0204999931, + 0.000250005716, + 0.0211874973, + -0.0097499853, + 0.00625000009, + 0.0, + 0.0193124767, + 0.0221874248, + 0.290687472, + 0.410999984, + -0.0355625153, + 0.0719374642, + 0.504749954, + 0.197812557, + 0.43187505, + -0.0289999973, + -0.0238124859, + 0.00900001545, + 0.0331874862, + 0.0205625538, + 0.0143125532, + -0.0122499466, + -0.00287494669, + 0.0226875301, + -0.0125000002, + -0.00406250963, + 0.114124969, + -0.00187492371, + 0.00499997148, + 0.0005624771, + 0.0603750236, + 0.0413125046, + 0.0, + -0.00312500005, + -0.0036874772, + 0.030687524, + -0.00249996199, + -0.00462503452, + -0.00062503817, + 0.0109374998 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 6, + 1, + 6, + 1, + 3, + 6, + 0, + 6, + 6, + 0, + 4, + 3, + 3, + 6, + 6, + 3, + 3, + 5, + 1, + 4, + 6, + 0, + 3, + 6, + 0, + 4, + 4, + 1, + 4, + 3, + 6, + 6, + 5, + 6, + 0, + 0, + 4, + 4, + 3, + 3, + 3, + 2, + 0, + 2, + 6, + 4, + 3, + 4, + 4, + 1, + 4, + 4, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.7109375, + -0.833984375, + 0.998046875, + -0.1875, + -0.2421875, + -0.91796875, + 0.0859375, + -0.91796875, + -0.416015625, + -0.87109375, + -0.013671875, + -0.625, + -0.9375, + -0.328125, + -0.23046875, + -0.9375, + -0.03125, + 0.953125, + -0.875, + 0.75, + -0.884765625, + -0.47265625, + 0.0, + 0.25, + 0.96875, + -0.572265625, + 0.2734375, + -0.8984375, + -0.3515625, + -0.125, + -0.92578125, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.8984375, + -0.5, + -0.90234375, + -0.876953125, + 0.78125, + -0.908203125, + 0.078125, + 0.0390625, + 0.921875, + -0.859375, + -0.375, + -0.875, + -0.125, + -0.59375, + 0.1171875, + -0.375, + -0.876953125, + 0.21875, + 0.0, + 0.4140625, + 0.078125, + -0.537109375, + 0.21875, + 0.71875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5761021.0, + 275876.0, + 102178.711, + 34120.0, + 83036.5625, + 37850.9688, + 86894.0938, + 25679.4062, + 13741.0, + 3785.47852, + 25262.5625, + 6729.0, + 7848.89062, + 27754.8867, + 17075.5938, + 1992.65625, + 3004.03613, + 1458.5, + 3853.75, + 4979.43262, + 4372.7207, + 19951.5625, + 2657.3125, + 7091.43994, + 7233.25195, + 7562.64844, + 8655.66406, + 53756.9883, + 26663.4062, + 5709.49219, + 1228.41284, + 1481.09375, + 889.214844, + 185.777832, + 1742.24023, + 182.5, + 1096.0, + 3389.25, + 507.875, + 255.291016, + 3000.23584, + 1553.80859, + 2905.51465, + 14280.0625, + 41555.8398, + 1078.82812, + 6063.05469, + 3406.46094, + 2120.42749, + 14600.3066, + 4212.02637, + 18324.7773, + 4093.39844, + 18361.4785, + 13940.6406, + 37206.0586, + 18875.1875, + 17571.3906, + 21098.7598, + 652.042847, + 4124.07031, + 813.436768, + 419.856567, + -0.0234375, + 0.0, + 0.0, + 0.0231249817, + -0.0681623444, + 0.212650105, + 0.206712529, + -0.0126874922, + 0.0, + 0.0, + 0.0, + 0.0, + 0.00106248853, + 0.0, + 0.0, + 0.001249981, + 0.0451250076, + -0.0213125236, + 0.0244000442, + 0.165649995, + -0.0768499374, + -0.0135624884, + -0.00981245097, + 0.033062458, + 0.0261750221, + 0.00505003938, + -0.0326999687, + -0.00463752775, + 0.001249981, + 0.0, + 0.00462493906, + 0.00118751533, + 0.208762556, + -0.303737462, + 0.16813755, + -0.00929994602, + -0.05123749, + 0.0103250509, + 0.0109874252, + -0.0015125752, + 0.0122374538, + -0.0224499702, + -0.00720005063, + 0.0108624464, + 0.0122374063, + 0.0142374039, + -0.0036999702, + 0.0579875, + -0.00244994159, + 0.00167498586, + 0.0656250045, + 0.00450010318, + -0.00170001981, + -0.0057624816, + -0.000387382519, + 0.000249910372, + -0.00749998121, + -0.00531249074, + 0.0, + -0.00312500005, + 0.0676875114, + -0.00575008383, + 0.0209500324, + -0.000674915325 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 6, + 4, + 4, + 0, + 1, + 0, + 0, + 4, + 6, + 6, + 4, + 3, + 4, + 6, + 6, + 0, + 6, + 6, + 0, + 0, + 3, + 6, + 4, + 3, + 2, + 0, + 3, + 4, + 1, + 2, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 6, + 6, + 6, + 6, + 5, + 5, + 0, + 2, + 6, + 1, + 4, + 2, + 6, + 4, + 2, + 0, + 2, + 4, + 4, + 5, + 1, + 5, + 3, + 2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.125, + -0.0703125, + 0.998046875, + -0.796875, + -0.7109375, + 0.1796875, + -0.06640625, + -0.1875, + -0.2421875, + -0.8515625, + 0.0859375, + -0.833984375, + 0.4140625, + -0.5, + 0.3125, + -0.8984375, + -0.90234375, + -0.328125, + -0.23046875, + -0.92578125, + 0.0390625, + 0.0078125, + -0.875, + -0.8984375, + 0.9921875, + -0.375, + -0.40625, + 0.546875, + 0.25, + 0.1875, + 0.4765625, + -0.5625, + -0.25, + -0.890625, + -0.8984375, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.9375, + -0.90234375, + -0.88671875, + -0.876953125, + 0.6875, + 0.78125, + 0.078125, + -0.4375, + -0.908203125, + -0.572265625, + 0.84375, + -0.78125, + -0.876953125, + -0.421875, + -0.4375, + 0.4765625, + 0.6875, + 0.9453125, + 0.9921875, + 0.96875, + 0.21484375, + 0.96875, + -0.125, + 0.5625, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5728183.0, + 341347.0, + 89176.9844, + 36449.0, + 80253.8125, + 53591.7305, + 15604.5625, + 27907.8906, + 13655.0, + 3182.625, + 29050.625, + 31077.5469, + 29639.293, + 6333.02344, + 1255.73303, + 2018.39062, + 4059.04688, + 1458.5, + 3828.5, + 2218.48096, + 3646.89648, + 18223.875, + 3000.9375, + 2847.40308, + 11828.9453, + 21948.3984, + 31571.8906, + 6195.30469, + 580.078308, + 411.701782, + 540.247925, + 1191.41797, + 1360.78125, + 1629.81152, + 707.264648, + 182.5, + 1096.0, + 3335.125, + 496.5, + 2132.23242, + 2147.29004, + 1887.58496, + 5745.59766, + 4609.28125, + 16403.9062, + 963.1875, + 3810.78125, + 5832.5918, + 3041.229, + 14897.9844, + 2674.51489, + 35364.7656, + 22977.8789, + 32801.1562, + 4369.01562, + 3606.42188, + 309.727295, + 713.103149, + 166.943878, + 93.4369659, + 99.4389648, + 289.16217, + 162.770844, + 0.00981254596, + -0.273750037, + 0.0, + 0.00281248102, + -0.0034500123, + -0.046912577, + 0.0492124557, + 0.00476250658, + 0.0, + 0.0, + 0.0, + 0.0, + 0.000212478641, + 0.0, + 0.0, + 0.000249958044, + 0.174649999, + 0.136192605, + -0.0181825645, + 0.00628757477, + 0.0324749947, + -0.00496253977, + -0.0950250626, + 0.0121974945, + -0.0149649624, + -0.00217752461, + 0.0365100391, + 0.000197553643, + 0.000249958044, + 0.0, + -0.0243875515, + 0.00644750614, + 0.00831489544, + 0.0703775436, + -0.0153024672, + 0.00438508997, + 0.0133225443, + -0.000115013121, + -0.0108650206, + 0.00769748678, + -0.014427471, + -0.00107760436, + 0.0202350616, + -7.74383589e-05, + -2.4938583e-05, + 0.0151599888, + 0.02222519, + 0.0784127265, + 0.0, + 0.0182974823, + 0.00675001135, + -0.00906248111, + 0.0078125, + -0.0217024814, + -0.00898752268, + 0.00819997769, + -0.0363374725, + 0.116662502, + 0.00410003681, + -0.0143850325, + 0.00142755511, + -0.00877246913, + 0.0349275582, + -0.0135099413 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 0, + 3, + 4, + 3, + 6, + 6, + 0, + 6, + 6, + 3, + 4, + 3, + 4, + 6, + 6, + 1, + 1, + 5, + 1, + 3, + 6, + 3, + 6, + 4, + 0, + 4, + 4, + 1, + 1, + 4, + 6, + 2, + 6, + 6, + 0, + 0, + 6, + 6, + 2, + 6, + 3, + 3, + 4, + 4, + 3, + 6, + 6, + 5, + 0, + 4, + 0, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.7109375, + -0.8359375, + 0.0859375, + -0.1875, + -0.2421875, + -0.884765625, + 0.0859375, + 0.125, + 0.75, + 0.078125, + 0.0, + -0.8984375, + -0.873046875, + -0.328125, + -0.23046875, + -0.9375, + 0.25, + 0.953125, + -0.875, + 0.3203125, + -0.92578125, + -0.833984375, + -0.048828125, + -0.22265625, + 0.90625, + -0.06640625, + 0.875, + -0.9375, + -0.25, + -0.9375, + -0.8125, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.974609375, + -0.8671875, + -0.876953125, + -0.28125, + -0.908203125, + -0.8671875, + 0.078125, + 0.0390625, + -0.9375, + -0.91796875, + -0.84375, + -0.91796875, + -0.875, + 0.125, + 0.515625, + 0.265625, + 0.5, + -0.8984375, + -0.88671875, + 0.9375, + 0.546875, + 0.3125, + 0.4296875, + 0.26953125, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5728642.5, + 255113.0, + 133207.281, + 36584.0, + 91186.75, + 35548.2969, + 93699.6719, + 27456.7188, + 13632.0, + 3702.5127, + 22190.5, + 4512.03516, + 6447.9375, + 23369.4473, + 29350.875, + 2144.82812, + 3275.96484, + 1458.5, + 3818.0, + 2653.23267, + 1911.27246, + 14716.5, + 2315.71875, + 2751.05859, + 1887.73193, + 5114.9375, + 7999.44336, + 15294.2383, + 17981.3047, + 6713.03125, + 41243.043, + 858.015625, + 1360.78125, + 1465.30371, + 1107.87854, + 182.5, + 1096.0, + 3318.5, + 496.5, + 176.486572, + 1231.77637, + 1277.93164, + 601.574951, + 13737.75, + 42442.4609, + 1061.32812, + 6308.35938, + 3536.43945, + 3955.78784, + 964.220032, + 2657.12402, + 3648.74609, + 7620.5, + 6808.89062, + 1707.75793, + 7556.51172, + 10003.916, + 6294.99121, + 17288.8418, + 5419.25, + 5357.00488, + 3914.58838, + 4289.72656, + -0.0680376068, + -0.00210008631, + 0.0, + 0.0005624771, + -0.01087246, + -0.00498247147, + 0.00938997325, + -0.0218601227, + 0.0, + 0.0, + 0.0, + 0.0, + 4.25338767e-05, + 0.0, + 0.0, + 4.99725356e-05, + 0.0677425414, + -0.13069497, + 0.00698852539, + 0.00599498767, + -0.0506176017, + -0.00748004904, + 0.0592076294, + 0.464832604, + 0.244289398, + -0.00577316293, + -0.00479803095, + -0.000585460686, + 4.99725356e-05, + 0.0, + 0.000829505909, + 0.00162944791, + 0.354407042, + -0.0288980007, + -0.0594554916, + 0.035281945, + 0.04586301, + -0.00146188738, + -0.0335118286, + -0.000848102558, + 0.0131019596, + 0.00868945103, + 0.00391454715, + -0.00704803457, + -0.00933551788, + -0.00642299652, + 0.0761019737, + 0.0120394705, + -0.00616550446, + 0.00349693303, + 0.14967452, + 0.00336446776, + -0.0163326263, + 0.0304924976, + -0.00469503412, + 0.000104904175, + 0.0, + -5.00679016e-06, + 0.00669555692, + 0.000285530085, + 0.00137052534, + 0.0209949501, + -0.0165277477, + -0.00180492399 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 5, + 3, + 4, + 3, + 6, + 6, + 0, + 6, + 6, + 4, + 4, + 3, + 6, + 4, + 0, + 4, + 6, + 3, + 1, + 3, + 6, + 3, + 4, + 3, + 0, + 4, + 4, + 1, + 2, + 0, + 0, + 0, + 5, + 6, + 0, + 0, + 5, + 1, + 6, + 0, + 6, + 4, + 1, + 2, + 6, + 3, + 6, + 4, + 0, + 4, + 6, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.734375, + -0.8359375, + 0.0859375, + -0.1875, + -0.2421875, + -0.873046875, + 0.0859375, + 0.84375, + -0.875, + -0.2421875, + -0.375, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.9375, + -0.796875, + 0.953125, + -0.875, + -0.90234375, + -0.8046875, + 0.140625, + 0.9921875, + -0.873046875, + 0.0, + -0.06640625, + 0.875, + -0.9375, + -0.25, + -0.8984375, + -0.25, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.9375, + -0.03125, + -0.03125, + -0.0390625, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + 0.15625, + -0.466796875, + -0.876953125, + 0.1328125, + -0.833984375, + -0.03125, + -0.7109375, + -0.59375, + -0.876953125, + 0.25, + -0.8515625, + 0.921875, + 0.546875, + 0.3125, + 0.50390625, + 0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5769419.5, + 248863.0, + 129287.602, + 36835.0, + 88026.0, + 41180.5781, + 107800.602, + 27411.6875, + 13632.0, + 2010.40723, + 22144.0625, + 2422.9209, + 6427.90625, + 15828.2324, + 22551.3438, + 2225.03125, + 2317.78809, + 1458.5, + 3818.0, + 1457.77979, + 590.955566, + 16240.75, + 2247.78125, + 2247.01343, + 2587.02539, + 4324.47656, + 9542.96875, + 20205.4121, + 12050.6953, + 6337.03125, + 29893.123, + 860.417969, + 1360.78125, + 213.583008, + 1326.94385, + 182.5, + 1096.0, + 3318.5, + 496.5, + 91.4921875, + 1404.94922, + 852.278564, + 308.276855, + 5152.625, + 42729.7031, + 1061.32812, + 6019.97656, + 869.963013, + 1923.36328, + 2498.85376, + 2625.67969, + 2516.74219, + 4970.1875, + 8414.40625, + 15574.959, + 14619.0781, + 22739.543, + 30480.7051, + 19840.8672, + 5543.79688, + 4732.65967, + 3621.31177, + 5322.66797, + -0.0136075979, + -0.000419998163, + 0.0, + 0.000112533569, + 0.00676288595, + -0.0522169136, + -0.00529909134, + 0.0432529934, + 0.0, + 0.0, + 0.0, + 0.0, + 8.48770196e-06, + 0.0, + 0.0, + 1.00135803e-05, + -0.0637639984, + 0.0394859314, + -0.0120398523, + 0.00393896131, + 0.0131790163, + -0.0127864843, + -0.00760860462, + -0.0218489654, + -0.0319669731, + 0.00228290563, + -0.000959587109, + -0.000117111209, + 1.00135803e-05, + 0.0, + 0.000165939331, + 0.000325870526, + 0.135910228, + -0.123020649, + 0.0821804032, + 0.00118904118, + -0.00464563398, + 0.0302453991, + -0.00988903083, + -0.00154466636, + 0.00262041087, + 0.00852031726, + -0.00374231348, + 0.0154953478, + -0.00375957484, + 0.00554037094, + -0.00296707149, + -0.00941705704, + 0.0022354126, + 0.0108169559, + -0.0134196281, + 0.00656204252, + -0.000401449215, + 0.00386104593, + -0.00258874893, + 0.000598716724, + 0.0, + 0.00135402684, + 0.00224056258, + 0.00123195653, + 0.00923347473, + -0.00678443909, + 0.00132389076, + -0.00330553064 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 0, + 3, + 6, + 3, + 6, + 6, + 0, + 6, + 4, + 6, + 4, + 3, + 6, + 4, + 0, + 4, + 1, + 2, + 0, + 3, + 6, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 3, + 3, + 0, + 0, + 5, + 6, + 0, + 0, + 4, + 1, + 6, + 6, + 6, + 6, + 4, + 2, + 1, + 2, + 6, + 2, + 1, + 5, + 4, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.734375, + -0.8359375, + 0.0859375, + -0.1875, + -0.2421875, + -0.9375, + 0.0859375, + 0.125, + -0.875, + -0.869140625, + -0.375, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.890625, + -0.908203125, + 0.953125, + -0.875, + -0.876953125, + 0.998046875, + 0.1171875, + 0.9921875, + -0.169921875, + -0.75, + 0.5390625, + 0.875, + -0.9375, + -0.25, + -0.8984375, + -0.873046875, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.125, + 0.625, + 0.03125, + -0.0390625, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + 0.796875, + 0.30078125, + -0.869140625, + -0.92578125, + 0.50390625, + -0.439453125, + -0.1640625, + -0.59375, + -0.22265625, + -0.875, + -0.52734375, + -0.65625, + -0.06640625, + 0.96875, + 0.25, + 0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5779889.5, + 251058.0, + 126886.445, + 36838.0, + 91365.0625, + 46038.6719, + 110277.016, + 27342.6875, + 13632.0, + 1260.3291, + 22180.6875, + 2041.55762, + 9415.10938, + 12557.2246, + 21868.3359, + 2240.1875, + 2325.31641, + 1458.5, + 3818.0, + 66.8986816, + 1208.20215, + 16295.75, + 2226.0, + 2030.91992, + 1691.04883, + 3069.71875, + 14833.3281, + 17398.4805, + 15566.082, + 6197.59375, + 28563.2773, + 845.347656, + 1360.78125, + 182.624023, + 992.40625, + 182.5, + 1096.0, + 3318.5, + 496.5, + 285.444153, + 101.974609, + 2655.66675, + 1927.08301, + 9015.875, + 42665.6172, + 1061.32812, + 5931.66406, + 3590.28027, + 576.590332, + 1954.34351, + 764.756836, + 1245.76172, + 11498.0273, + 8008.0625, + 16670.3848, + 24204.2754, + 6175.92188, + 21338.0117, + 32982.1875, + 5101.5, + 1586.31909, + 2740.88135, + 5277.48828, + -0.00272159581, + -8.40187058e-05, + 0.0, + 2.25067142e-05, + 0.00135250099, + -0.0104433065, + -0.000927352929, + 0.000804758107, + 0.0, + 0.0, + 0.0, + 0.0, + 1.71661384e-06, + 0.0, + 0.0, + 2.0027162e-06, + -0.105502702, + -0.000852775585, + 0.106887296, + -0.0782129318, + 9.21249375e-05, + 0.0369791053, + -0.028491497, + -0.00146217353, + -0.00639338512, + 0.00045661928, + -0.00019187927, + -2.34127056e-05, + 2.0027162e-06, + 0.0, + 3.31878655e-05, + 6.51359587e-05, + -0.0287292488, + 0.0178951267, + 0.00745725632, + 0.0341191292, + 0.00673408527, + -0.0110588074, + -0.0329165459, + -0.0145837786, + 0.000524091709, + 0.0227996353, + 0.00555400876, + 0.00170407293, + 0.0204330441, + -0.00394191733, + -0.000593423843, + -0.00188341143, + 0.000804710377, + 0.0146546364, + -0.000907850277, + 0.0071661952, + -0.00125536916, + 0.00168228149, + 0.023082925, + 0.0133070946, + 0.0, + 0.0021965981, + -0.0088160513, + -0.000437498093, + 0.0165012367, + -0.000165843972, + 0.000264739996, + -0.000661087048 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 1, + 3, + 0, + 3, + 6, + 6, + 0, + 6, + 4, + 6, + 4, + 3, + 6, + 2, + 6, + 4, + 3, + 2, + 0, + 3, + 6, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 3, + 4, + 3, + 0, + 5, + 6, + 0, + 0, + 5, + 6, + 0, + 5, + 0, + 5, + 0, + 2, + 4, + 1, + 1, + 2, + 1, + 2, + 4, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.734375, + -0.8359375, + 0.0859375, + -0.1875, + -0.2421875, + -0.9375, + 0.0859375, + 0.125, + -0.875, + 0.4765625, + -0.375, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.890625, + -0.90234375, + 0.953125, + -0.875, + -0.876953125, + -0.9375, + 0.998046875, + 0.9921875, + -0.375, + -0.9375, + 0.5390625, + 0.875, + -0.9375, + -0.25, + -0.8984375, + -0.873046875, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + 0.5, + -0.8046875, + 0.125, + 0.015625, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + 0.59375, + -0.873046875, + 0.125, + 0.71875, + 0.1171875, + 0.9375, + 0.1171875, + -0.59375, + -0.2734375, + 0.38671875, + 0.16015625, + -0.8125, + -0.06640625, + -0.75, + 0.2421875, + 0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5786345.0, + 252567.0, + 129921.688, + 37078.0, + 92834.5625, + 46452.2188, + 110678.359, + 27671.9844, + 13632.0, + 1521.69043, + 22261.6875, + 2311.92969, + 10548.3594, + 24145.0527, + 21849.9453, + 2240.1875, + 2361.51074, + 1458.5, + 3818.0, + 177.72168, + 552.041992, + 16260.6875, + 2226.0, + 1914.77246, + 888.809509, + 2731.85938, + 16005.9062, + 20634.0352, + 15958.4414, + 6866.0625, + 28551.9492, + 845.347656, + 1360.78125, + 182.624023, + 935.646973, + 182.5, + 1096.0, + 3318.5, + 496.5, + 194.945801, + 57.786377, + 1024.41357, + 2624.53516, + 10395.5, + 42602.7344, + 1061.32812, + 5931.66406, + 1794.61621, + 2527.85254, + 882.946228, + 587.89978, + 2106.35156, + 291.599335, + 6818.67188, + 16638.8203, + 12291.2666, + 11985.9531, + 8960.62109, + 8928.88086, + 4692.01562, + 1586.89307, + 3097.01636, + 5277.48828, + -0.000544357288, + -1.67846683e-05, + 0.0, + 4.48226956e-06, + 0.000270462042, + -0.00208873744, + -0.000185489655, + 0.000160932541, + 0.0, + 0.0, + 0.0, + 0.0, + 3.81469732e-07, + 0.0, + 0.0, + 3.81469732e-07, + -0.11642056, + 0.0921419188, + -0.0109550478, + 0.172214702, + -0.0106136324, + 0.0213490482, + 0.0136852264, + -0.0105949407, + -0.00127868657, + 9.13620024e-05, + -3.83377082e-05, + -4.67300424e-06, + 3.81469732e-07, + 0.0, + 6.67572021e-06, + 1.3065338e-05, + 0.122656345, + -0.00665864954, + 0.0167707447, + -0.00447111158, + 0.00383319869, + 0.00925960578, + -0.0775581375, + 0.0316381939, + 0.000104808809, + 0.000340795523, + -0.033251144, + 0.00775985746, + 0.00869398098, + -0.00278835301, + -0.000118684773, + -0.000376701355, + -0.000385189051, + 0.00446395902, + -0.00161361694, + 0.00757665653, + -0.00032849313, + -0.00248155603, + 0.00123400695, + 0.0132489204, + 0.0, + 0.000439357769, + -0.0040667057, + -0.000274991995, + 0.00435285596, + -3.31878655e-05, + 5.29289246e-05, + -0.000132179266 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 0, + 0, + 6, + 6, + 2, + 3, + 0, + 3, + 6, + 6, + 0, + 6, + 4, + 6, + 4, + 3, + 0, + 3, + 0, + 4, + 2, + 6, + 0, + 3, + 6, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 1, + 1, + 6, + 6, + 5, + 6, + 0, + 0, + 4, + 6, + 6, + 4, + 4, + 6, + 1, + 2, + 6, + 1, + 4, + 6, + 1, + 3, + 4, + 0, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + 0.1796875, + -0.796875, + -0.734375, + -0.8359375, + 0.0859375, + -0.1875, + -0.2421875, + -0.9375, + 0.0859375, + -0.40625, + -0.875, + 0.4765625, + -0.375, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.890625, + -0.869140625, + 0.953125, + -0.875, + 0.125, + 0.25, + 0.1171875, + 0.9921875, + -0.65625, + -0.8828125, + 0.5390625, + 0.875, + -0.9375, + -0.25, + -0.8984375, + -0.873046875, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.431640625, + 0.30078125, + -0.876953125, + -0.76953125, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + -0.8515625, + -0.884765625, + -0.87890625, + -0.734375, + 0.640625, + -0.439453125, + -0.7109375, + -0.59375, + -0.52734375, + -0.67578125, + 0.5625, + -0.875, + -0.06640625, + -0.625, + 0.2421875, + 0.46875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5789880.0, + 250458.0, + 130533.531, + 37112.0, + 89851.375, + 46834.4375, + 110713.422, + 27718.5156, + 13632.0, + 1335.30469, + 22263.0625, + 1732.78809, + 10851.625, + 24320.2852, + 21771.2891, + 2240.1875, + 2366.62891, + 1458.5, + 3818.0, + 393.336182, + 1036.1377, + 16259.4375, + 2226.0, + 1496.89258, + 725.791931, + 2355.38281, + 16370.9844, + 10369.9609, + 9014.11621, + 7278.98438, + 28502.7656, + 845.347656, + 1360.78125, + 182.624023, + 927.789062, + 182.5, + 1096.0, + 3318.5, + 496.5, + 100.13324, + 38.9777832, + 1653.229, + 263.053711, + 10486.9375, + 42602.7344, + 1061.32812, + 5931.66406, + 1462.12695, + 1316.36133, + 0.704772949, + 562.176636, + 908.738281, + 8773.25195, + 6689.34375, + 16815.9023, + 9140.41016, + 8582.49219, + 15870.4941, + 9329.6084, + 4506.46875, + 1616.97961, + 3217.28564, + 5277.48828, + -0.000108909611, + -3.33786011e-06, + 0.0, + 8.58306919e-07, + 5.41687004e-05, + -0.000417709351, + -3.70979324e-05, + 3.21865082e-05, + 0.0, + 0.0, + 0.0, + 0.0, + 9.53674331e-08, + 0.0, + 0.0, + 9.53674331e-08, + -0.15284653, + 0.0343158729, + -0.00219097151, + -0.172098547, + -0.00168828969, + 0.0153298853, + -0.0116614345, + 0.040292263, + -0.000255727762, + 1.83105476e-05, + -7.62939453e-06, + -9.53674316e-07, + 9.53674331e-08, + 0.0, + 1.33514402e-06, + 2.5749207e-06, + 0.00483207731, + -0.00522203464, + -0.00457105646, + 0.00365257263, + -0.909941494, + -0.0150747299, + 0.52290529, + 0.339665234, + 0.00465097418, + -0.00164794922, + 0.00083818438, + 6.81400343e-05, + 0.00336389546, + -0.000340271014, + -2.37464901e-05, + -7.5340271e-05, + 3.41415398e-05, + 0.000647449517, + -0.00234251027, + 0.0018248558, + 0.0162563324, + -0.020881176, + 0.00181365013, + -0.000181245807, + 0.0, + 8.78334031e-05, + -0.000306367874, + 0.0128062246, + 0.000870609307, + -6.67572021e-06, + 1.05857853e-05, + -2.64167793e-05 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 6, + 4, + 4, + 0, + 3, + 0, + 0, + 6, + 6, + 6, + 2, + 0, + 6, + 6, + 6, + 0, + 6, + 6, + 0, + 4, + 3, + 4, + 4, + 0, + 4, + 6, + 3, + 0, + 1, + 6, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 4, + 1, + 4, + 3, + 5, + 6, + 0, + 0, + 6, + 1, + 4, + 6, + 2, + 0, + 4, + 4, + 4, + 1, + 1, + 1, + 1, + 2, + 1, + 3, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + -0.552734375, + -0.796875, + -0.734375, + 0.1796875, + -0.375, + -0.1875, + -0.2421875, + -0.76953125, + 0.0859375, + -0.8359375, + -0.625, + 0.5390625, + -0.50390625, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.9375, + -0.03125, + 0.953125, + -0.875, + -0.8359375, + 0.9921875, + 0.4765625, + 0.4140625, + -0.396484375, + -0.625, + 0.25, + -0.67578125, + -0.9375, + -0.25, + -0.8984375, + -0.873046875, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.8984375, + -0.15234375, + -0.8125, + 0.375, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + -0.908203125, + -0.51953125, + 0.6796875, + -0.833984375, + -0.8125, + 0.6328125, + -0.5, + 0.6171875, + -0.359375, + 0.0546875, + -0.1015625, + -0.06640625, + 0.08984375, + -0.59375, + -0.763671875, + 0.875, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5789094.5, + 248548.0, + 134369.781, + 37117.0, + 87110.9375, + 83474.0312, + 67303.375, + 27718.5156, + 13607.0, + 4513.85352, + 22288.875, + 33217.0703, + 18118.4922, + 7004.89062, + 22493.0352, + 2240.1875, + 2366.62891, + 1458.5, + 3825.5, + 1222.02344, + 171.560059, + 16250.875, + 2231.0, + 1250.375, + 10187.0625, + 12716.2988, + 6814.23828, + 5755.4375, + 1869.21753, + 21428.875, + 12407.1504, + 845.347656, + 1360.78125, + 182.624023, + 927.789062, + 182.5, + 1096.0, + 3311.0, + 479.3125, + 368.290527, + 1052.35742, + 300.004395, + 99.6333008, + 10562.375, + 42602.7344, + 1052.8125, + 5931.66406, + 1829.83813, + 1893.19531, + 10232.6953, + 25268.1406, + 13102.3359, + 7481.54932, + 4063.47656, + 2301.96094, + 2374.29858, + 3300.35938, + 245.433212, + 278.523438, + 9644.99219, + 1792.04053, + 16015.3047, + 16620.8398, + -2.17437755e-05, + -6.6757201e-07, + 0.0, + 1.90734866e-07, + 1.08718878e-05, + -8.35418687e-05, + -7.43865985e-06, + 6.43730164e-06, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.00599327078, + -0.00512561807, + -0.00545959501, + 0.0117704868, + 0.0906220898, + -0.0212478638, + 0.0112210279, + -0.0544415489, + -5.11646285e-05, + 3.62396236e-06, + -1.52587893e-06, + -1.90734866e-07, + 0.0, + 0.0, + 2.86102306e-07, + 4.76837158e-07, + -0.038309481, + 0.0102029806, + 0.00135564804, + -0.00129051215, + 0.000883579254, + -0.00139474869, + 0.00133934023, + -9.82284564e-06, + -0.000687408436, + 0.0086376667, + 0.00104422576, + -0.000818920147, + 0.047791101, + -0.0145030022, + -0.0228611957, + -0.00413236627, + -0.0264698025, + -0.00184583664, + 0.0, + -0.00027542116, + 0.00194010732, + -0.00506334333, + -0.00159168243, + 0.00696182251, + -0.00201559067, + -0.000947189343, + 0.00267190929, + -0.0216555595, + 0.00312614441, + 0.000251960766, + 0.00243616104, + 0.00717992801 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ], + [ + { + "feature": [ + 0, + 0, + 6, + 4, + 4, + 0, + 3, + 0, + 0, + 6, + 6, + 6, + 0, + 0, + 6, + 6, + 6, + 0, + 6, + 6, + 3, + 4, + 3, + 4, + 4, + 2, + 4, + 6, + 3, + 0, + 3, + 6, + 3, + 4, + 6, + 0, + 4, + 4, + 1, + 4, + 0, + 0, + 2, + 5, + 6, + 0, + 0, + 6, + 0, + 4, + 6, + 5, + 4, + 6, + 6, + 4, + 1, + 1, + 1, + 1, + 0, + 1, + 6, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2, + -2 + ], + "threshold": [ + 0.09375, + -0.0703125, + -0.552734375, + -0.796875, + -0.734375, + 0.1796875, + -0.375, + -0.1875, + -0.2421875, + -0.76953125, + 0.0859375, + -0.8359375, + 0.484375, + 0.5390625, + -0.50390625, + -0.8984375, + -0.9375, + -0.328125, + -0.23046875, + -0.9375, + 0.375, + 0.953125, + -0.875, + -0.875, + 0.9921875, + -0.65625, + 0.890625, + -0.396484375, + -0.625, + 0.25, + 0.875, + -0.9375, + -0.25, + -0.8984375, + -0.873046875, + -0.390625, + -0.6171875, + 0.359375, + 0.07421875, + -0.8984375, + 0.0625, + -0.03125, + -0.09375, + 0.78125, + -0.8671875, + 0.078125, + 0.0390625, + -0.875, + 0.125, + 0.6796875, + -0.833984375, + 0.875, + 0.2578125, + -0.876953125, + -0.876953125, + -0.453125, + 0.0546875, + 0.421875, + -0.06640625, + 0.08984375, + 0.3359375, + -0.67578125, + 0.0859375, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "value": [ + 5786671.5, + 248503.0, + 146815.5, + 37081.0, + 87038.875, + 84460.9766, + 61481.5, + 27739.1562, + 13607.0, + 5308.37988, + 22288.875, + 33007.9297, + 17626.5332, + 7081.25, + 17885.3359, + 2248.25, + 2366.62891, + 1458.5, + 3825.5, + 1182.8877, + 115.316406, + 16250.875, + 2231.0, + 2135.13672, + 10460.0859, + 10045.0625, + 5561.35693, + 6544.28125, + 1899.15527, + 21834.4609, + 12071.8105, + 845.347656, + 1325.96875, + 182.624023, + 927.789062, + 182.5, + 1096.0, + 3311.0, + 479.3125, + 348.211426, + 675.949219, + 158.875, + 106.986694, + 10562.375, + 42602.7344, + 1052.8125, + 5931.66406, + 740.380859, + 1344.13672, + 9834.80469, + 25472.7324, + 2927.56445, + 6312.17773, + 49520.1289, + 47705.1758, + 2315.95508, + 3389.71875, + 332.276031, + 278.523438, + 9779.41406, + 873.022522, + 17130.4512, + 22536.7812, + -4.38690176e-06, + -9.53674331e-08, + 0.0, + 0.0, + 2.09808354e-06, + -1.67846683e-05, + -1.52587893e-06, + 1.28746035e-06, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.00119857793, + -0.00102519989, + -0.00102243421, + 0.00423669815, + 0.0355192684, + 0.00224418635, + -0.4328309, + -0.0108882906, + -1.02519989e-05, + 7.62939464e-07, + -2.86102306e-07, + -4.76837165e-08, + 0.0, + 0.0, + 9.53674331e-08, + 9.53674331e-08, + 0.017323399, + -0.0427024849, + -0.00251212134, + -0.000853920006, + 0.000176715854, + -0.000278949738, + 0.00026788711, + -1.9550323e-06, + 0.0180500038, + -0.000187397003, + -0.000533771527, + -0.00193014147, + -0.0124995233, + 0.00064306258, + 0.00621042261, + -0.00046606065, + -0.00615043659, + -0.000190353399, + 0.0, + -5.51223748e-05, + -0.00117449765, + 0.0199400913, + -0.000318336504, + 0.0013923645, + -0.000403118145, + -0.000189399725, + 0.00844993629, + -0.00415315619, + 0.000625228917, + 0.000487232202, + 0.00612344733, + -0.00574922562 + ], + "children_left": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ], + "children_right": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] + } + ] + ], + "config": { + "output_dir": "/eos/home-p/pviscone/www/L1T/l1teg-ML/tasks/EB_ptRegr/step4_BDT_conifer/my-conifer-prj", + "project_name": "my_prj", + "backend": "xilinxhls", + "input_precision": "ap_fixed<10,1,AP_RND_CONV,AP_SAT>", + "threshold_precision": "ap_fixed<10, 1,AP_RND_CONV,AP_SAT>", + "score_precision": "ap_fixed<12, 3,AP_RND_CONV,AP_SAT>", + "xilinx_part": "xcvu13p-flga2577-2-e", + "clock_period": 4.16666666, + "unroll": true, + "accelerator_config": null + }, + "metadata": [ + { + "version": "0.0.0", + "host": "pcms-cmgos-fw1", + "user": "pviscone", + "time": 1755204932.635013 + } + ] +} \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h new file mode 100644 index 0000000000000..28505c00adfd6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h @@ -0,0 +1,70 @@ +#ifndef L2TKELEREGRESSION_REF_H +#define L2TKELEREGRESSION_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include "conifer.h" + +namespace edm { + class ParameterSet; + class ParameterSetDescription; +} // namespace edm + +namespace l1ct { + class L2TkEleRegressionEmulator { + public: + enum class ModelType { null = 0, EB_v0 = 1 }; + + L2TkEleRegressionEmulator(const std::vector& eta_bins, + const std::vector& model_types, + const std::vector& model_paths, + int debug); + + L2TkEleRegressionEmulator(const edm::ParameterSet& iConfig); + static edm::ParameterSetDescription getParameterSetDescription(); + + class Model { + public: + Model() = default; + virtual ~Model() = default; + + virtual pt_t compute_ptCorr(const EGIsoEleObjEmu& ele) const = 0; + }; + + class Model_EB_v0 : public Model { + public: + Model_EB_v0(const std::string& model_path, int debug); + + l1ct::pt_t compute_ptCorr(const EGIsoEleObjEmu& ele) const override; + + typedef ap_fixed<10, 1, AP_RND_CONV, AP_SAT> bdt_feature_t; + typedef ap_fixed<12, 3, AP_RND_CONV, AP_SAT> bdt_out_t; + + private: + std::unique_ptr> model_; + bdt_feature_t scale(float x, float min_x, int bitshift, float inf = -1) const { + const float delta = x - min_x; + if (bitshift >= 0) { + const float denom = float(1u << unsigned(bitshift)); + return bdt_feature_t(inf + delta / denom); + } + const float mul = float(1u << unsigned(-bitshift)); + return bdt_feature_t(inf + delta * mul); + } + }; + + void toFirmware(const std::vector>& encoded_in, ap_uint<64> encoded_fw[]) const; + + void run(const std::vector& in_eles, std::vector& out_eles) const; + + private: + std::vector eta_bins_; + std::vector> models_; + }; + +} // namespace l1ct + +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index f30b0838a9803..ef6b10baded57 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -8,6 +8,8 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/transform.h" @@ -15,6 +17,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h" #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" #include "L1Trigger/DemonstratorTools/interface/utilities.h" @@ -29,6 +32,8 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { explicit L1TCtL2EgProducer(const edm::ParameterSet &); ~L1TCtL2EgProducer() override; + // edm::ParameterSetDescription getParameterSetDescription(); + private: ap_uint<64> encodeLayer1(const EGIsoObjEmu &egiso) const; ap_uint<128> encodeLayer1(const EGIsoEleObjEmu &egiso) const; @@ -231,6 +236,7 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { std::string tkEleInstanceLabel_; l1ct::L2EgSorterEmulator l2egsorter; l1ct::L2EgEncoderEmulator l2encoder; + l1ct::L2TkEleRegressionEmulator l2tkeleregression; edm::EDGetTokenT> pfObjsToken_; l1ct::L1EGPuppiIsoAlgo l2EgPuppiIsoAlgo_; l1ct::L1EGPuppiIsoAlgo l2ElePuppiIsoAlgo_; @@ -249,6 +255,7 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) tkEleInstanceLabel_(conf.getParameter("tkEleInstanceLabel")), l2egsorter(conf.getParameter("sorter")), l2encoder(conf.getParameter("encoder")), + l2tkeleregression(conf.getParameter("eleRegression")), pfObjsToken_(consumes>(conf.getParameter("l1PFObjects"))), l2EgPuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEm")), l2ElePuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEle")), @@ -270,6 +277,27 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) L1TCtL2EgProducer::~L1TCtL2EgProducer() {} +// edm::ParameterSetDescription L1TCtL2EgProducer::getParameterSetDescription() { +// edm::ParameterSetDescription desc; +// desc.add>("tkEgs", std::vector()); +// desc.add>("tkEms", std::vector()); +// desc.add>("tkElectrons", std::vector()); +// desc.add("egStaInstanceLabel", "L1EGamma"); +// desc.add("tkEmInstanceLabel", "L1TkEm"); +// desc.add("tkEleInstanceLabel", "L1TkElectron"); +// desc.add("sorter", l1ct::L2EgSorterEmulator::getParameterSetDescription()); +// desc.add("encoder", l1ct::L2EgEncoderEmulator::getParameterSetDescription()); +// desc.add("eleRegression", l1ct::L2TkEleRegressionEmulator::getParameterSetDescription()); +// desc.add("l1PFObjects", edm::InputTag("l1pfProducer")); +// desc.add("puppiIsoParametersTkEm", l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); +// desc.add("puppiIsoParametersTkEle", l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); +// desc.add("writeInPattern", false); +// desc.add("writeOutPattern", false); +// desc.add("inPatternFile", PatternWriter(conf).getParameterSetDescription()); +// desc.add("outPatternFile", PatternWriter(conf).getParameterSetDescription()); +// return desc; +// } + ap_uint<64> L1TCtL2EgProducer::encodeLayer1(const EGIsoObjEmu &egiso) const { ap_uint<64> ret = 0; ret(EGIsoObjEmu::BITWIDTH, 0) = egiso.pack(); @@ -345,8 +373,12 @@ void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::Ev } std::vector out_photons_emu; + std::vector sorted_eles_emu; std::vector out_eles_emu; - l2egsorter.run(*regions, out_photons_emu, out_eles_emu); + l2egsorter.run(*regions, out_photons_emu, sorted_eles_emu); + + // Apply electron regression + l2tkeleregression.run(sorted_eles_emu, out_eles_emu); // PUPPI isolation auto &pfObjs = iEvent.get(pfObjsToken_); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index f8ac89ffa96ed..14019fe072f47 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -52,6 +52,12 @@ nTKELE_OUT=cms.uint32(12), nTKPHO_OUT=cms.uint32(12), ), + eleRegression=cms.PSet( + eta_bins=cms.vdouble(1.5), + model_types=cms.vuint32(1), + model_paths=cms.vstring( + "L1Trigger/Phase2L1ParticleFlow/data/egamma/TkElePtRegr_EB_sigVsBkg_v0_conifer.json") + ), puppiIsoParametersTkEm = cms.PSet( pfIsoType = cms.string("PUPPI"), pfPtMin = cms.double(1.), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py index 7004f87b03a96..da87c8ad72cad 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py @@ -31,7 +31,8 @@ ) ) phase2_hgcalV11.toModify(l1tPFClustersFromL1EGClusters, - corrector = "", # In this setup, TP's are already calibrated correctly :-) + corrector = "L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root", + # In this setup, TP's are already calibrated correctly :-) # L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel_110X.root", resol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp new file mode 100644 index 0000000000000..aebc31b933d99 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp @@ -0,0 +1,102 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h" + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +l1ct::L2TkEleRegressionEmulator::L2TkEleRegressionEmulator(const edm::ParameterSet& iConfig) + : L2TkEleRegressionEmulator(iConfig.getParameter>("eta_bins"), + iConfig.getParameter>("model_types"), + iConfig.getParameter>("model_paths"), + iConfig.getUntrackedParameter("debug", 0)) {} + +edm::ParameterSetDescription l1ct::L2TkEleRegressionEmulator::getParameterSetDescription() { + edm::ParameterSetDescription desc; + desc.add>("eta_bins", std::vector{1.5}); + desc.add>("model_types", std::vector{1}); + desc.add>( + "model_paths", + std::vector{"L1Trigger/Phase2L1ParticleFlow/data/egamma/eb_v0/eta_bin0_emf_bin0/model.json"}); + desc.addUntracked("debug", 0); + return desc; +} + +#endif + +l1ct::L2TkEleRegressionEmulator::L2TkEleRegressionEmulator(const std::vector& eta_bins, + const std::vector& model_types, + const std::vector& model_paths, + int debug) { + if (model_types.size() != model_paths.size() || model_types.size() != eta_bins.size()) { + throw std::invalid_argument("Size of model_types and model_paths must be the same"); + } + // check the eta bins are in increasing order + for (size_t i = 1; i < eta_bins.size(); ++i) { + if (eta_bins[i] <= eta_bins[i - 1]) { + throw std::invalid_argument("Eta bins must be in increasing order"); + } + } + for (unsigned int i = 0; i < model_types.size(); ++i) { + auto type = ModelType(model_types[i]); + if (type == ModelType::EB_v0) { + models_.push_back(std::make_unique(model_paths[models_.size()], debug)); + } else if (type == ModelType::null) { + models_.push_back(nullptr); + } else { + throw std::invalid_argument("Unsupported regression algorithm"); + } + eta_bins_.push_back(eta_bins[i]); + } +} + +l1ct::L2TkEleRegressionEmulator::Model_EB_v0::Model_EB_v0(const std::string& model_path, int debug) { +#ifdef CMSSW_GIT_HASH + auto resolvedFileName = edm::FileInPath(model_path).fullPath(); +#else + auto resolvedFileName = model_path; +#endif + model_ = std::make_unique>(resolvedFileName); +} + +l1ct::pt_t l1ct::L2TkEleRegressionEmulator::Model_EB_v0::compute_ptCorr(const EGIsoEleObjEmu& ele) const { + bdt_feature_t scaled_ID = bdt_feature_t(ele.floatIDScore()); + bdt_feature_t scaled_cl_eta = scale(fabs(ele.floatEta()), 0., 0); + bdt_feature_t scaled_cltk_absDphi = scale(ele.hwTkCaloDphi.to_float(), 0., 5); + bdt_feature_t scaled_tk_chi2RPhi = scale(ele.hwTkRedChi2RPhi.to_float(), 0., 3); + bdt_feature_t scaled_cl_pt = scale(ele.floatPt(), 0., 5); + bdt_feature_t scaled_cl_ss = scale(ele.hwCaloShowerShape.to_float(), 0., -1); + bdt_feature_t scaled_cltk_ptRatio = scale(ele.hwCaloTkPtRatio.to_float(), 0., 0); + + // Run BDT inference + std::vector inputs = {scaled_ID, + scaled_cl_eta, + scaled_cltk_absDphi, + scaled_tk_chi2RPhi, + scaled_cl_pt, + scaled_cl_ss, + scaled_cltk_ptRatio}; + + std::vector bdt_output = model_->decision_function(inputs); + + bdt_out_t corr_factor = bdt_out_t(bdt_output[0]); + float corr_pt = ele.hwPt.to_float() * (1. + corr_factor.to_float()); + return pt_t(corr_pt); +} + +void l1ct::L2TkEleRegressionEmulator::run(const std::vector& in_eles, + std::vector& out_eles) const { + out_eles.clear(); + for (const auto& ele : in_eles) { + EGIsoEleObjEmu corrected_ele = ele; + // find the eta bin the electron falls into and apply the corresponding regression model + for (size_t i = 0; i < eta_bins_.size(); ++i) { + if (std::abs(ele.floatVtxEta()) < eta_bins_[i]) { + if (models_[i]) { + corrected_ele.hwPt = models_[i]->compute_ptCorr(ele); + } + break; + } + } + out_eles.push_back(corrected_ele); + } +} \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index 2dfa4a54b7c13..032f34bc577db 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -827,6 +827,13 @@ EGIsoEleObjEmu &PFTkEGAlgoEmulator::addEGIsoEleToPF(std::vector egiso.srcCluster = calo.src; egiso.srcTrack = track.src; egiso.hwIDScore = bdtScore; + // additional variables for pt regression on layer-2 + egiso.hwTkRedChi2RPhi = track.hwRedChi2RPhi; + egiso.hwTkCaloDphi = abs(track.hwPhi - calo.hwPhi); + egiso.hwCaloShowerShape = calo.hwShowerShape; + + ap_ufixed<16, 0> tk_invPt = l1ct::invert_with_shift, 1024>(track.hwPt); + egiso.hwCaloTkPtRatio = l1ct::Scales::makeCaloTkPtRatio(calo.hwPt * tk_invPt); egobjs.push_back(egiso); if (debug_ > 2) From a9c75a9850f0ea64d2bc30a652efd3f31aec1eb6 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Wed, 17 Jun 2026 14:03:15 +0200 Subject: [PATCH 90/92] add pset descriptions --- .../interface/egamma/L1EGPuppiIsoAlgo.h | 3 + .../interface/egamma/l2egencoder_ref.h | 5 +- .../interface/egamma/l2egsorter_ref.h | 4 +- .../plugins/L1TCtL2EgProducer.cc | 72 +++++++++++++------ .../src/egamma/L1EGPuppiIsoAlgo.cc | 11 +++ .../src/egamma/l2egencoder_ref.cpp | 7 ++ .../src/egamma/l2egsorter_ref.cpp | 10 +++ 7 files changed, 89 insertions(+), 23 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h index 175b9d8d2cc5f..593838f3fd6e9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h @@ -11,6 +11,7 @@ #include "DataFormats/L1TParticleFlow/interface/egamma.h" #include "DataFormats/L1TParticleFlow/interface/puppi.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" namespace l1ct { @@ -46,6 +47,8 @@ namespace l1ct { public: L1EGPuppiIsoAlgo(const L1EGPuppiIsoAlgoConfig& config) : config_(config) {} L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet); + static edm::ParameterSetDescription getParameterSetDescription(); + virtual ~L1EGPuppiIsoAlgo() = default; void run(const EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, EGIsoObjsEmu& outL1EGs, z0_t z0 = 0) const; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h index 010fa8801d692..792901fe1de08 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h @@ -7,7 +7,8 @@ namespace edm { class ParameterSet; -} + class ParameterSetDescription; +} // namespace edm namespace l1ct { @@ -20,6 +21,8 @@ namespace l1ct { L2EgEncoderEmulator(const edm::ParameterSet& iConfig); + static edm::ParameterSetDescription getParameterSetDescription(); + void toFirmware(const std::vector>& encoded_in, ap_uint<64> encoded_fw[]) const; std::vector> encodeLayer2EgObjs(const std::vector& photons, diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h index 9e1e162c2d943..1bd74db5153c9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h @@ -11,7 +11,8 @@ namespace edm { class ParameterSet; -} + class ParameterSetDescription; +} // namespace edm namespace l1ct { @@ -21,6 +22,7 @@ namespace l1ct { : nREGIONS(nRegions), nEGPerRegion(nEGPerRegion), nEGOut(nEGOut), debug_(debug) {} L2EgSorterEmulator(const edm::ParameterSet &iConfig); + static edm::ParameterSetDescription getParameterSetDescription(); virtual ~L2EgSorterEmulator() {} diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index ef6b10baded57..9c816f0d5761d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -32,7 +32,7 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { explicit L1TCtL2EgProducer(const edm::ParameterSet &); ~L1TCtL2EgProducer() override; - // edm::ParameterSetDescription getParameterSetDescription(); + edm::ParameterSetDescription getParameterSetDescription(); private: ap_uint<64> encodeLayer1(const EGIsoObjEmu &egiso) const; @@ -142,6 +142,28 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { channelSpecs); } + static edm::ParameterSetDescription getParameterSetDescription() { + edm::ParameterSetDescription desc; + desc.add("format"); + desc.add("outputFilename"); + desc.add("outputFileExtension"); + desc.add("nFramesPerBX"); + desc.add("TMUX"); + desc.add("maxLinesPerFile"); + desc.add("eventsPerFile"); + + edm::ParameterSetDescription channelDesc; + channelDesc.add("interface"); + channelDesc.add("id"); + channelDesc.add("TMUX"); + channelDesc.add("nWords"); + channelDesc.add>("channels"); + + desc.addVPSet("channels", channelDesc); + + return desc; + } + struct RegionLinkMetadata { l1t::demo::LinkId linkId; unsigned int nTrailingWords; @@ -277,26 +299,34 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) L1TCtL2EgProducer::~L1TCtL2EgProducer() {} -// edm::ParameterSetDescription L1TCtL2EgProducer::getParameterSetDescription() { -// edm::ParameterSetDescription desc; -// desc.add>("tkEgs", std::vector()); -// desc.add>("tkEms", std::vector()); -// desc.add>("tkElectrons", std::vector()); -// desc.add("egStaInstanceLabel", "L1EGamma"); -// desc.add("tkEmInstanceLabel", "L1TkEm"); -// desc.add("tkEleInstanceLabel", "L1TkElectron"); -// desc.add("sorter", l1ct::L2EgSorterEmulator::getParameterSetDescription()); -// desc.add("encoder", l1ct::L2EgEncoderEmulator::getParameterSetDescription()); -// desc.add("eleRegression", l1ct::L2TkEleRegressionEmulator::getParameterSetDescription()); -// desc.add("l1PFObjects", edm::InputTag("l1pfProducer")); -// desc.add("puppiIsoParametersTkEm", l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); -// desc.add("puppiIsoParametersTkEle", l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); -// desc.add("writeInPattern", false); -// desc.add("writeOutPattern", false); -// desc.add("inPatternFile", PatternWriter(conf).getParameterSetDescription()); -// desc.add("outPatternFile", PatternWriter(conf).getParameterSetDescription()); -// return desc; -// } +edm::ParameterSetDescription L1TCtL2EgProducer::getParameterSetDescription() { + edm::ParameterSetDescription desc; + + edm::ParameterSetDescription inputDesc; + inputDesc.add("pfProducer"); + inputDesc.add>("regions"); + + desc.addVPSet("tkEgs", inputDesc); + desc.addVPSet("tkEms", inputDesc); + desc.addVPSet("tkElectrons", inputDesc); + desc.add("egStaInstanceLabel", "L1CtEgEE"); + desc.add("tkEmInstanceLabel", "L1CtTkEm"); + desc.add("tkEleInstanceLabel", "L1CtTkElectron"); + desc.add("sorter", l1ct::L2EgSorterEmulator::getParameterSetDescription()); + desc.add("encoder", l1ct::L2EgEncoderEmulator::getParameterSetDescription()); + desc.add("eleRegression", + l1ct::L2TkEleRegressionEmulator::getParameterSetDescription()); + desc.add("l1PFObjects", edm::InputTag("l1pfProducer")); + desc.add("puppiIsoParametersTkEm", + l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); + desc.add("puppiIsoParametersTkEle", + l1ct::L1EGPuppiIsoAlgo::getParameterSetDescription()); + desc.add("writeInPattern", false); + desc.add("writeOutPattern", false); + desc.add("inPatternFile", PatternWriter::getParameterSetDescription()); + desc.add("outPatternFile", PatternWriter::getParameterSetDescription()); + return desc; +} ap_uint<64> L1TCtL2EgProducer::encodeLayer1(const EGIsoObjEmu &egiso) const { ap_uint<64> ret = 0; diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc index 4d77d7866c0c0..5fa3ae653af6f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc @@ -10,6 +10,17 @@ L1EGPuppiIsoAlgo::L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet) pSet.getParameter("dRMax"), pSet.getParameter("pfCandReuse")) {} +edm::ParameterSetDescription L1EGPuppiIsoAlgo::getParameterSetDescription() { + edm::ParameterSetDescription desc; + desc.add("pfIsoType"); + desc.add("pfPtMin"); + desc.add("dZ"); + desc.add("dRMin"); + desc.add("dRMax"); + desc.add("pfCandReuse"); + return desc; +} + void L1EGPuppiIsoAlgo::run(const EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, EGIsoObjsEmu& outL1EGs, diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp index 64ffeb9f13e24..ea4a5157d7c7e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp @@ -5,10 +5,17 @@ using namespace l1ct; #ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" l1ct::L2EgEncoderEmulator::L2EgEncoderEmulator(const edm::ParameterSet& pset) : L2EgEncoderEmulator(pset.getParameter("nTKELE_OUT"), pset.getParameter("nTKPHO_OUT")) {} +edm::ParameterSetDescription l1ct::L2EgEncoderEmulator::getParameterSetDescription() { + edm::ParameterSetDescription desc; + desc.add("nTKELE_OUT", 12); + desc.add("nTKPHO_OUT", 12); + return desc; +} #endif void L2EgEncoderEmulator::toFirmware(const std::vector>& encoded_in, ap_uint<64> encoded_fw[]) const { diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp index 64bc9314ff5ce..19871e3fb98c4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp @@ -10,12 +10,22 @@ using namespace l1ct; #ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" l1ct::L2EgSorterEmulator::L2EgSorterEmulator(const edm::ParameterSet &pset) : L2EgSorterEmulator(pset.getParameter("nREGIONS"), pset.getParameter("nEGPerRegion"), pset.getParameter("nEGOut"), pset.getUntrackedParameter("debug", 0)) {} + +edm::ParameterSetDescription l1ct::L2EgSorterEmulator::getParameterSetDescription() { + edm::ParameterSetDescription desc; + desc.add("nREGIONS", 5); + desc.add("nEGPerRegion", 16); + desc.add("nEGOut", 12); + desc.addUntracked("debug", 0); + return desc; +} #endif void L2EgSorterEmulator::toFirmware(const std::vector &out_photons, From d43a9d8a8c8be41a851c2b10a134a8ddae91e333 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Mon, 22 Jun 2026 11:30:19 +0200 Subject: [PATCH 91/92] codeformat --- .../interface/egamma/l2tkeleregression_ref.h | 2 +- .../Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h index 28505c00adfd6..fbb64f65e9349 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2tkeleregression_ref.h @@ -67,4 +67,4 @@ namespace l1ct { } // namespace l1ct -#endif \ No newline at end of file +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp index aebc31b933d99..2ecbaad35107f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2tkeleregression_ref.cpp @@ -99,4 +99,4 @@ void l1ct::L2TkEleRegressionEmulator::run(const std::vector& in_ } out_eles.push_back(corrected_ele); } -} \ No newline at end of file +} From 8975514f226968f3beee7142ad77f5e5389e2973 Mon Sep 17 00:00:00 2001 From: Gianluca Date: Mon, 22 Jun 2026 11:36:44 +0200 Subject: [PATCH 92/92] codeformat NNVTX --- L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h b/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h index 4d535041e0957..0c785daf06a6b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/NNVtxAssoc.h @@ -214,4 +214,4 @@ void EmuNetworkSelector(const l1ct::TkObj& t, const l1ct::PVObjEmu& v, l1ct::nn_ #endif -#endif \ No newline at end of file +#endif