4 #include <cp3_llbb/Framework/interface/CandidatesProducer.h>
6 #include <DataFormats/PatCandidates/interface/Tau.h>
7 #include <DataFormats/PatCandidates/interface/TauPFSpecific.h>
10 #include <Math/VectorUtil.h>
13 enum class GenMatch { Electron = 1, Muon = 2, TauElectron = 3, TauMuon = 4, Tau = 5, NoMatch = 6 };
17 using MatchResult = std::pair<GenMatch, const reco::GenParticle*>;
20 TausProducer(
const std::string& name,
const ROOT::TreeGroup&
tree,
const edm::ParameterSet& config):
28 virtual void doConsumes(
const edm::ParameterSet& config, edm::ConsumesCollector&& collector)
override {
29 m_taus_token = collector.consumes<std::vector<pat::Tau>>(config.getUntrackedParameter<edm::InputTag>(
"src"));
30 m_pruned_token = collector.consumes<std::vector<reco::GenParticle>>(config.getUntrackedParameter<edm::InputTag>(
"pruned_gen_particles", edm::InputTag(
"prunedGenParticles")));
33 virtual void produce(edm::Event& event,
const edm::EventSetup& eventSetup)
override;
38 edm::EDGetTokenT<std::vector<pat::Tau>> m_taus_token;
39 edm::EDGetTokenT<std::vector<reco::GenParticle>> m_pruned_token;
42 MatchResult LeptonGenMatch(
const LorentzVector& p4,
const std::vector<reco::GenParticle>& genParticles)
44 static constexpr
int electronPdgId = 11, muonPdgId = 13, tauPdgId = 15;
45 static constexpr
double dR2_threshold = std::pow(0.2, 2);
47 static const std::map<int, double> pt_thresholds = {
48 { electronPdgId, 8 }, { muonPdgId, 8 }, { tauPdgId, 15 }
51 using pair = std::pair<int, bool>;
52 static const std::map<pair, GenMatch> genMatches = {
53 { { electronPdgId,
false }, GenMatch::Electron }, { { electronPdgId,
true }, GenMatch::TauElectron },
54 { { muonPdgId,
false }, GenMatch::Muon }, { { muonPdgId,
true }, GenMatch::TauMuon },
55 { { tauPdgId,
false }, GenMatch::Tau }, { { tauPdgId,
true }, GenMatch::Tau }
58 MatchResult result(GenMatch::NoMatch,
nullptr);
59 double match_dr2 = dR2_threshold;
63 for(
const reco::GenParticle& particle : genParticles) {
64 const bool isTauProduct = particle.statusFlags().isDirectPromptTauDecayProduct();
65 if((!particle.statusFlags().isPrompt() && !isTauProduct) || !particle.statusFlags().isLastCopy())
continue;
67 const int abs_pdg = std::abs(particle.pdgId());
68 if(!pt_thresholds.count(abs_pdg))
continue;
70 const auto gen_particle_p4 = LorentzVector(particle.pt(), particle.eta(), particle.phi(), particle.energy());
71 const auto particle_p4 = abs_pdg == tauPdgId ? GetFinalStateMomentum(particle,
true,
true) : gen_particle_p4;
73 const double dr2 = ROOT::Math::VectorUtil::DeltaR2(p4, particle_p4);
74 if(dr2 >= match_dr2)
continue;
75 if(particle_p4.pt() <= pt_thresholds.at(abs_pdg))
continue;
78 result.first = genMatches.at(pair(abs_pdg, isTauProduct));
79 result.second = &particle;
84 inline void FindFinalStateDaughters(
const reco::GenParticle& particle, std::vector<const reco::GenParticle*>& daughters,
85 const std::set<int>& pdg_to_exclude = {})
87 if(particle.daughterRefVector().empty()) {
88 const int abs_pdg = std::abs(particle.pdgId());
89 if(!pdg_to_exclude.count(abs_pdg))
90 daughters.push_back(&particle);
92 for(
const auto& daughter : particle.daughterRefVector())
93 FindFinalStateDaughters(*daughter, daughters, pdg_to_exclude);
97 inline LorentzVector GetFinalStateMomentum(
const reco::GenParticle& particle,
bool excludeInvisible,
98 bool excludeLightLeptons)
100 using set = std::set<int>;
101 using pair = std::pair<bool, bool>;
102 static const set empty = {};
103 static const set light_leptons = { 11, 13 };
104 static const set invisible_particles = { 12, 14, 16 };
105 static const set light_and_invisible = Framework::union_sets({light_leptons, invisible_particles});
107 static const std::map<pair, const set*> to_exclude {
108 { pair(
false,
false), &empty }, { pair(
true,
false), &invisible_particles },
109 { pair(
false,
true), &light_leptons }, { pair(
true,
true), &light_and_invisible },
112 std::vector<const reco::GenParticle*> daughters;
113 FindFinalStateDaughters(particle, daughters, *to_exclude.at(pair(excludeInvisible,
false)));
116 for(
auto daughter : daughters){
117 if(excludeLightLeptons && light_leptons.count(std::abs(daughter->pdgId())) && daughter->statusFlags().isDirectTauDecayProduct())
continue;
118 p4 += daughter->p4();
127 BRANCH(decayMode, std::vector<float>);
128 BRANCH(dz, std::vector<float>);
129 BRANCH(gen_truth, std::vector<int>);
130 BRANCH(IDmap, std::vector<tauDiscriminatorMap>);
Definition: CandidatesProducer.h:9
ROOT::TreeGroup tree
Access point to output tree.
Definition: Producer.h:132
Definition: TausProducer.h:15
virtual void produce(edm::Event &event, const edm::EventSetup &eventSetup) override
Main method of the producer, called for each event.
Definition: TausProducer.cc:7
virtual void doConsumes(const edm::ParameterSet &config, edm::ConsumesCollector &&collector) override
Hook for the CMSSW consumes interface.
Definition: TausProducer.h:28