-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Phase2 L1 NN Tau #30505
Phase2 L1 NN Tau #30505
Changes from all commits
17617ee
07fb8f8
4271dea
7d6243d
ca32d1e
dee6362
ec1594d
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,39 @@ | ||
#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOW_L1NNTAU_H | ||
#define L1TRIGGER_PHASE2L1PARTICLEFLOW_L1NNTAU_H | ||
|
||
#include <vector> | ||
|
||
#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 "DataFormats/L1TParticleFlow/interface/PFTau.h" | ||
#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" | ||
#include "L1Trigger/Phase2L1ParticleFlow/interface/TauNNId.h" | ||
|
||
using namespace l1t; | ||
|
||
class L1NNTauProducer : public edm::stream::EDProducer<> { | ||
public: | ||
explicit L1NNTauProducer(const edm::ParameterSet &); | ||
~L1NNTauProducer() override; | ||
|
||
private: | ||
std::unique_ptr<TauNNId> fTauNNId_; | ||
void addTau(const l1t::PFCandidate &iCand, | ||
const l1t::PFCandidateCollection &iParts, | ||
std::unique_ptr<PFTauCollection> &outputTaus); | ||
float deltaR(const l1t::PFCandidate &iPart1, const l1t::PFCandidate &iPart2); | ||
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override; | ||
|
||
double fSeedPt_; | ||
double fConeSize_; | ||
double fTauSize_; | ||
int fMaxTaus_; | ||
int fNParticles_; | ||
edm::EDGetTokenT<vector<l1t::PFCandidate> > fL1PFToken_; | ||
}; | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOWS_TAUNNID_H | ||
#define L1TRIGGER_PHASE2L1PARTICLEFLOWS_TAUNNID_H | ||
|
||
#include <string> | ||
#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" | ||
#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" | ||
|
||
class TauNNId { | ||
public: | ||
TauNNId(); | ||
~TauNNId(); | ||
|
||
void initialize(const std::string &iName, const std::string &iWeightFile, int iNParticles); | ||
void SetNNVectorVar(); | ||
float EvaluateNN(); | ||
float compute(const l1t::PFCandidate &iSeed, l1t::PFCandidateCollection &iParts); | ||
|
||
std::string fInput_; | ||
int fNParticles_; | ||
unique_ptr<float> fPt_; | ||
unique_ptr<float> fEta_; | ||
unique_ptr<float> fPhi_; | ||
unique_ptr<float> fId_; | ||
|
||
private: | ||
tensorflow::Session *session_; | ||
tensorflow::GraphDef *graphDef_; | ||
std::vector<float> NNvectorVar_; | ||
}; | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#include "L1Trigger/Phase2L1ParticleFlow/interface/L1NNTauProducer.hh" | ||
#include <TLorentzVector.h> | ||
#include <cmath> | ||
|
||
L1NNTauProducer::L1NNTauProducer(const edm::ParameterSet& cfg) | ||
: fSeedPt_(cfg.getParameter<double>("seedpt")), | ||
fConeSize_(cfg.getParameter<double>("conesize")), | ||
fTauSize_(cfg.getParameter<double>("tausize")), | ||
fMaxTaus_(cfg.getParameter<int>("maxtaus")), | ||
fNParticles_(cfg.getParameter<int>("nparticles")), | ||
fL1PFToken_(consumes<vector<l1t::PFCandidate> >(cfg.getParameter<edm::InputTag>("L1PFObjects"))) { | ||
std::string lNNFile = cfg.getParameter<std::string>("NNFileName"); //,"L1Trigger/Phase2L1Taus/data/tau_3layer.pb"); | ||
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. delete commented-out code |
||
fTauNNId_ = std::make_unique<TauNNId>(); | ||
if (lNNFile.find("v0") == std::string::npos) | ||
fTauNNId_->initialize("input_1:0", lNNFile, fNParticles_); | ||
else if (lNNFile.find("v0") != std::string::npos) | ||
fTauNNId_->initialize("dense_1_input:0", lNNFile, fNParticles_); | ||
produces<l1t::PFTauCollection>("L1PFTausNN"); | ||
} | ||
|
||
void L1NNTauProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { | ||
edm::Handle<l1t::PFCandidateCollection> l1PFCandidates; | ||
iEvent.getByToken(fL1PFToken_, l1PFCandidates); | ||
|
||
l1t::PFCandidateCollection pfChargedHadrons; | ||
l1t::PFCandidateCollection pfChargedHadrons_sort; | ||
l1t::PFCandidateCollection pfChargedHadrons_seeds; | ||
for (const auto& l1PFCand : *l1PFCandidates) | ||
if ((l1PFCand.id() == l1t::PFCandidate::ChargedHadron || l1PFCand.id() == l1t::PFCandidate::Electron) && | ||
std::abs(l1PFCand.eta()) < 2.5) | ||
pfChargedHadrons_sort.push_back(l1PFCand); | ||
std::sort(pfChargedHadrons_sort.begin(), pfChargedHadrons_sort.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { | ||
return (i.pt() > j.pt()); | ||
}); | ||
auto lTaus = std::make_unique<l1t::PFTauCollection>(); | ||
if (pfChargedHadrons_sort.empty()) { | ||
if (lTaus->empty()) { | ||
PFTau dummy; | ||
lTaus->push_back(dummy); | ||
} | ||
iEvent.put(std::move(lTaus), "L1PFTausNN"); | ||
return; | ||
} | ||
pfChargedHadrons_seeds.push_back(pfChargedHadrons_sort[0]); | ||
for (unsigned int i0 = 1; i0 < pfChargedHadrons_sort.size(); i0++) { | ||
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. could be range-based loop |
||
bool pMatch = false; | ||
for (unsigned int i1 = 0; i1 < pfChargedHadrons_seeds.size(); i1++) { | ||
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. could be range-based loop |
||
if (deltaR(pfChargedHadrons_seeds[i1], pfChargedHadrons_sort[i0]) < fConeSize_) | ||
pMatch = true; | ||
} | ||
if (pMatch) | ||
continue; | ||
pfChargedHadrons_seeds.push_back(pfChargedHadrons_sort[i0]); | ||
if (int(pfChargedHadrons_seeds.size()) > fMaxTaus_ - 1) | ||
break; | ||
} | ||
for (unsigned int i0 = 0; i0 < pfChargedHadrons_seeds.size(); i0++) { | ||
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. could be range-based loop |
||
addTau(pfChargedHadrons_seeds[i0], (*l1PFCandidates), lTaus); | ||
} | ||
if (lTaus->empty()) { | ||
PFTau dummy; | ||
lTaus->push_back(dummy); | ||
} | ||
std::sort(lTaus->begin(), lTaus->end(), [](l1t::PFTau i, l1t::PFTau j) { return (i.pt() > j.pt()); }); | ||
iEvent.put(std::move(lTaus), "L1PFTausNN"); | ||
} | ||
|
||
// create taus based on grid structure | ||
void L1NNTauProducer::addTau(const l1t::PFCandidate& iCand, | ||
const l1t::PFCandidateCollection& iParts, | ||
std::unique_ptr<l1t::PFTauCollection>& outputTaus) { | ||
l1t::PFCandidateCollection pfTauCands; | ||
TLorentzVector lTot; | ||
lTot.SetPtEtaPhiM(0, 0, 0, 0); | ||
TLorentzVector lCand; | ||
lCand.SetPtEtaPhiM(0, 0, 0, 0); | ||
int lId = 0; | ||
for (auto l1PFCand : iParts) { | ||
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. const auto& |
||
if (deltaR(iCand, l1PFCand) > fConeSize_) | ||
continue; | ||
TLorentzVector pVec; | ||
pVec.SetPtEtaPhiM(l1PFCand.pt(), l1PFCand.eta(), l1PFCand.phi(), 0); | ||
lTot += pVec; | ||
if (deltaR(iCand, l1PFCand) < fTauSize_ && | ||
(l1PFCand.id() == l1t::PFCandidate::Electron || l1PFCand.id() == l1t::PFCandidate::ChargedHadron || | ||
l1PFCand.id() == l1t::PFCandidate::Photon)) { | ||
lId++; | ||
lCand += pVec; | ||
} | ||
pfTauCands.push_back(l1PFCand); | ||
} | ||
if (lTot.Pt() < fSeedPt_) | ||
return; | ||
std::sort( | ||
pfTauCands.begin(), pfTauCands.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { return (i.pt() > j.pt()); }); | ||
float NN = fTauNNId_->compute(iCand, pfTauCands); | ||
math::PtEtaPhiMLorentzVector tempP4(lCand.Pt(), lCand.Eta(), lCand.Phi(), lCand.M()); | ||
l1t::PFTau l1PFTau(tempP4, NN, 0, lId); | ||
outputTaus->push_back(l1PFTau); | ||
} | ||
float L1NNTauProducer::deltaR(const l1t::PFCandidate& iPart1, const l1t::PFCandidate& iPart2) { | ||
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. |
||
float delta_r = 20; | ||
float pDPhi = fabs(iPart1.phi() - iPart2.phi()); | ||
if (pDPhi > 2. * M_PI - pDPhi) | ||
pDPhi = 2. * M_PI - pDPhi; | ||
delta_r = sqrt((iPart1.eta() - iPart2.eta()) * (iPart1.eta() - iPart2.eta()) + pDPhi * pDPhi); | ||
return delta_r; | ||
} | ||
L1NNTauProducer::~L1NNTauProducer() {} | ||
|
||
#include "FWCore/Framework/interface/MakerMacros.h" | ||
DEFINE_FWK_MODULE(L1NNTauProducer); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import FWCore.ParameterSet.Config as cms | ||
|
||
L1NNTauProducer = cms.EDProducer("L1NNTauProducer", | ||
seedpt = cms.double(20), | ||
conesize = cms.double(0.4), | ||
tausize = cms.double(0.1), | ||
maxtaus = cms.int32(5), | ||
nparticles = cms.int32(10), | ||
L1PFObjects = cms.InputTag("L1PFProducer","l1pfCandidates"), | ||
NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer.pb") | ||
) | ||
|
||
|
||
L1NNTauProducerPuppi = cms.EDProducer("L1NNTauProducer", | ||
seedpt = cms.double(20), | ||
conesize = cms.double(0.4), | ||
tausize = cms.double(0.1), | ||
maxtaus = cms.int32(5), | ||
nparticles = cms.int32(10), | ||
L1PFObjects = cms.InputTag("L1PFProducer","l1pfCandidates"), | ||
NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer_puppi.pb") | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#include "L1Trigger/Phase2L1ParticleFlow/interface/TauNNId.h" | ||
#include "FWCore/ParameterSet/interface/FileInPath.h" | ||
#include <cmath> | ||
|
||
TauNNId::TauNNId() { NNvectorVar_.clear(); } | ||
TauNNId::~TauNNId() { | ||
tensorflow::closeSession(session_); | ||
delete graphDef_; | ||
} | ||
void TauNNId::initialize(const std::string &iInput, const std::string &iWeightFile, int iNParticles) { | ||
edm::FileInPath fp(iWeightFile); | ||
graphDef_ = tensorflow::loadGraphDef(fp.fullPath()); | ||
session_ = tensorflow::createSession(graphDef_); | ||
fNParticles_ = iNParticles; | ||
fPt_ = std::make_unique<float>(fNParticles_); | ||
fEta_ = std::make_unique<float>(fNParticles_); | ||
fPhi_ = std::make_unique<float>(fNParticles_); | ||
fId_ = std::make_unique<float>(fNParticles_); | ||
fInput_ = iInput; | ||
} | ||
void TauNNId::SetNNVectorVar() { | ||
NNvectorVar_.clear(); | ||
for (int i0 = 0; i0 < fNParticles_; i0++) { | ||
NNvectorVar_.push_back(fPt_.get()[i0]); //pT | ||
NNvectorVar_.push_back(fEta_.get()[i0]); //dEta from jet axis | ||
NNvectorVar_.push_back(fPhi_.get()[i0]); //dPhi from jet axis | ||
if (fPt_.get()[i0] == 0) { | ||
for (int i1 = 0; i1 < 5; i1++) | ||
NNvectorVar_.push_back(0); | ||
continue; | ||
} | ||
NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Photon); // Photon | ||
NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron); // Electron | ||
NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon); // Muon | ||
NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::NeutralHadron); // Neutral Had | ||
NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron); // Charged Had | ||
} | ||
} | ||
float TauNNId::EvaluateNN() { | ||
tensorflow::Tensor input(tensorflow::DT_FLOAT, | ||
{1, (unsigned int)NNvectorVar_.size()}); //was {1,35} but get size mismatch, CHECK | ||
for (unsigned int i = 0; i < NNvectorVar_.size(); i++) { | ||
input.matrix<float>()(0, i) = float(NNvectorVar_[i]); | ||
} | ||
std::vector<tensorflow::Tensor> outputs; | ||
tensorflow::run(session_, {{fInput_, input}}, {"dense_4/Sigmoid:0"}, &outputs); | ||
float disc = outputs[0].matrix<float>()(0, 0); | ||
return disc; | ||
} //end EvaluateNN | ||
|
||
float TauNNId::compute(const l1t::PFCandidate &iSeed, l1t::PFCandidateCollection &iParts) { | ||
for (int i0 = 0; i0 < fNParticles_; i0++) { | ||
fPt_.get()[i0] = 0; | ||
fEta_.get()[i0] = 0; | ||
fPhi_.get()[i0] = 0; | ||
fId_.get()[i0] = 0; | ||
} | ||
std::sort(iParts.begin(), iParts.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { return (i.pt() > j.pt()); }); | ||
for (unsigned int i0 = 0; i0 < iParts.size(); i0++) { | ||
if (i0 > 10) | ||
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. why is this hardcoded? is it the same as the "nparticles" python parameter? if so, just use that... |
||
break; | ||
fPt_.get()[i0] = iParts[i0].pt(); | ||
fEta_.get()[i0] = iSeed.eta() - iParts[i0].eta(); | ||
float lDPhi = iSeed.phi() - iParts[i0].phi(); | ||
if (lDPhi > M_PI) | ||
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. |
||
lDPhi -= M_PI; | ||
if (lDPhi < -M_PI) | ||
lDPhi += M_PI; | ||
fPhi_.get()[i0] = lDPhi; | ||
fId_.get()[i0] = iParts[i0].id(); | ||
} | ||
SetNNVectorVar(); | ||
return EvaluateNN(); | ||
} |
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.
How big is the graph? I think we've typically shared the graph across the stream modules in an
edm::GlobalCache
.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.
also, a smart pointer could be used (though it seems like that isn't common practice for CMSSW TF code at the moment, something to be improved globally)