-
Notifications
You must be signed in to change notification settings - Fork 2
L1TSC82ProngJetModel #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
L1TSC82ProngJetModel #150
Changes from 11 commits
d5c7fbf
4bf12cb
9765ee3
64ead43
4146781
a20196a
bb02d43
da47c35
415e52f
2f9df92
912dfe4
c4fbe83
5fe0d52
039521f
5c3a721
85744a2
c0e2949
fd5052d
063a582
db3dc45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #ifndef L1TRIGGER_PHASE2L1PARTICLEFLOWS_L1TSC82ProngJetID_H | ||
| #define L1TRIGGER_PHASE2L1PARTICLEFLOWS_L1TSC82ProngJetID_H | ||
|
|
||
| #include "DataFormats/L1TParticleFlow/interface/PFJet.h" | ||
|
|
||
| //HLS4ML compiled emulator modeling | ||
| #include "ap_fixed.h" | ||
| #include "hls4ml/emulator.h" | ||
|
|
||
| class L1TSC82ProngJetID { | ||
| public: | ||
| L1TSC82ProngJetID(const std::shared_ptr<hls4mlEmulator::Model> 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<float> EvaluateNNFixed(); | ||
| std::vector<float> computeFixed(const l1t::PFJet &iJet); | ||
|
|
||
| private: | ||
| std::vector<inputtype> NNvectorVar_; | ||
| int fNParticles_; | ||
| unique_ptr<float[]> fPt_; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shoud these be
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
| unique_ptr<float[]> fPt_rel_; | ||
| unique_ptr<float[]> fDEta_; | ||
| unique_ptr<float[]> fDPhi_; | ||
| unique_ptr<float[]> fPt_log_; | ||
| unique_ptr<float[]> fMass_; | ||
| unique_ptr<float[]> fZ0_; | ||
| unique_ptr<float[]> fDxy_; | ||
| unique_ptr<int[]> fIs_filled_; | ||
| unique_ptr<float[]> fPuppi_weight_; | ||
| unique_ptr<int[]> fEmID_; | ||
| unique_ptr<float[]> fQuality_; | ||
|
|
||
| unique_ptr<int[]> fCharge_; | ||
| unique_ptr<int[]> fId_; | ||
| std::shared_ptr<hls4mlEmulator::Model> modelRef_; | ||
|
Comment on lines
+12
to
+41
|
||
|
|
||
| //bool isDebugEnabled_; | ||
| }; | ||
| #endif | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,106 @@ | ||||||||||
| #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 <cmath> | ||||||||||
| #include <vector> | ||||||||||
|
|
||||||||||
| #include <string> | ||||||||||
| #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<L1TSC82ProngJetID> fJetId_; | ||||||||||
| void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; | ||||||||||
|
|
||||||||||
| edm::EDGetTokenT<edm::View<l1t::PFJet>> const jets_; | ||||||||||
| double const fMinPt_; | ||||||||||
| double const fMaxEta_; | ||||||||||
| unsigned int const fMaxJets_; | ||||||||||
| int const fNParticles_; | ||||||||||
|
|
||||||||||
| hls4mlEmulator::ModelLoader loader; | ||||||||||
| std::shared_ptr<hls4mlEmulator::Model> model; | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| L1TSC82ProngJetProducer::L1TSC82ProngJetProducer(const edm::ParameterSet& cfg) | ||||||||||
| : jets_(consumes<edm::View<l1t::PFJet>>(cfg.getParameter<edm::InputTag>("jets"))), | ||||||||||
| fMinPt_(cfg.getParameter<double>("minPt")), | ||||||||||
| fMaxEta_(cfg.getParameter<double>("maxEta")), | ||||||||||
| fMaxJets_(cfg.getParameter<int>("maxJets")), | ||||||||||
| fNParticles_(cfg.getParameter<int>("nParticles")), | ||||||||||
| loader(hls4mlEmulator::ModelLoader(cfg.getParameter<string>("l1tSC82ProngJetModelPath"))) { | ||||||||||
|
henripetrow marked this conversation as resolved.
Outdated
|
||||||||||
| model = loader.load_model(); | ||||||||||
| fJetId_ = std::make_unique<L1TSC82ProngJetID>(model, fNParticles_); | ||||||||||
| produces<l1t::PFJetCollection>("l1tSC82ProngJets"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void L1TSC82ProngJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { | ||||||||||
| edm::Handle<edm::View<l1t::PFJet>> jets; | ||||||||||
| iEvent.getByToken(jets_, jets); | ||||||||||
| std::vector<l1t::PFJet> 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<float> 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<l1ct::JetTagClass> 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<edm::Ptr<l1t::PFCandidate>> 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<l1t::PFJetCollection> taggedJetsCollection(new l1t::PFJetCollection); | ||||||||||
| taggedJetsCollection->swap(taggedJets); | ||||||||||
| iEvent.put(std::move(taggedJetsCollection), "l1tSC82ProngJets"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void L1TSC82ProngJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { | ||||||||||
| edm::ParameterSetDescription desc; | ||||||||||
| desc.add<edm::InputTag>("jets", edm::InputTag("l1tSC8PFL1PuppiEmulator")); | ||||||||||
| desc.add<std::string>("l1tSC82ProngJetModelPath", std::string("L1TSC82ProngJetModel_v0")); | ||||||||||
|
||||||||||
| desc.add<std::string>("l1tSC82ProngJetModelPath", std::string("L1TSC82ProngJetModel_v0")); | |
| desc.add<std::string>("l1tSC82ProngJetModelPath", std::string("L1TSC82ProngJetModel_v0")); | |
| desc.add<double>("minPt", 0.); | |
| desc.add<double>("maxEta", 999.); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one makes sense, just set the maxEta value to 5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added minPt and maxEta.
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need a
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the new entry to the imports section. |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The file name should rather be
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed the filename. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TSC82ProngJetID.h" | ||
| #include "DataFormats/Math/interface/deltaPhi.h" | ||
|
henripetrow marked this conversation as resolved.
|
||
| #include <cmath> | ||
|
|
||
| L1TSC82ProngJetID::L1TSC82ProngJetID(const std::shared_ptr<hls4mlEmulator::Model> model, int iNParticles) | ||
| : modelRef_(model) { | ||
| NNvectorVar_.clear(); | ||
| fNParticles_ = iNParticles; | ||
|
|
||
| fPt_ = std::make_unique<float[]>(fNParticles_); | ||
| fPt_rel_ = std::make_unique<float[]>(fNParticles_); | ||
| fDEta_ = std::make_unique<float[]>(fNParticles_); | ||
| fDPhi_ = std::make_unique<float[]>(fNParticles_); | ||
| fPt_log_ = std::make_unique<float[]>(fNParticles_); | ||
| fMass_ = std::make_unique<float[]>(fNParticles_); | ||
| fZ0_ = std::make_unique<float[]>(fNParticles_); | ||
| fDxy_ = std::make_unique<float[]>(fNParticles_); | ||
| fIs_filled_ = std::make_unique<int[]>(fNParticles_); | ||
| fPuppi_weight_ = std::make_unique<float[]>(fNParticles_); | ||
| fEmID_ = std::make_unique<int[]>(fNParticles_); | ||
| fQuality_ = std::make_unique<float[]>(fNParticles_); | ||
|
|
||
| fId_ = std::make_unique<int[]>(fNParticles_); | ||
| fCharge_ = std::make_unique<int[]>(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<float> L1TSC82ProngJetID::EvaluateNNFixed() { | ||
| const int NInputs = 160; | ||
| prong_score prong_scores; | ||
| inputtype fillzero = 0.0; | ||
|
|
||
| inputtype modelInput[NInputs] = {}; // Do something | ||
| std::fill(modelInput, modelInput + NInputs, fillzero); | ||
|
|
||
| for (unsigned int i = 0; i < NNvectorVar_.size(); i++) { | ||
| modelInput[i] = NNvectorVar_[i]; | ||
| } | ||
|
Comment on lines
+54
to
+73
|
||
|
|
||
| modelRef_->prepare_input(modelInput); | ||
| modelRef_->predict(); | ||
| modelRef_->read_result(&prong_scores); | ||
|
|
||
| std::vector<float> prong_score_; | ||
| prong_score_.push_back(prong_scores.to_float()); | ||
|
|
||
| return prong_score_; | ||
| } //end EvaluateNNFixed | ||
|
|
||
| std::vector<float> 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<l1t::PFCandidate> i, edm::Ptr<l1t::PFCandidate> 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()); | ||
|
Comment on lines
+116
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we sure that the model training used these physical values and not the hardware ones?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the model training used physical values. |
||
|
|
||
| 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(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toGTWide()now fillshwNProngScorefromhwTagScores[0], but index 0 corresponds to the first jet tag score field ("b" in the default ordering). This will propagate the b-tag score into the WideJet n-prong field unless the hwTagScores packing has been repurposed accordingly. Please either sourcehwNProngScorefrom the actual n-prong score field, or document/update the hwTagScores layout so index 0 is guaranteed to be n-prong for WideJets.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this suggestion is wrong.