CP3-llbb Framework
TausProducer.h
1 #ifndef TAUS_PRODUCER
2 #define TAUS_PRODUCER
3 
4 #include <cp3_llbb/Framework/interface/CandidatesProducer.h>
5 
6 #include <DataFormats/PatCandidates/interface/Tau.h>
7 #include <DataFormats/PatCandidates/interface/TauPFSpecific.h>
8 
9 #include <utility>
10 #include <Math/VectorUtil.h>
11 
12 
13 enum class GenMatch { Electron = 1, Muon = 2, TauElectron = 3, TauMuon = 4, Tau = 5, NoMatch = 6 };
14 
15 class TausProducer: public CandidatesProducer<pat::Tau> {
16  private:
17  using MatchResult = std::pair<GenMatch, const reco::GenParticle*>;
18 
19  public:
20  TausProducer(const std::string& name, const ROOT::TreeGroup& tree, const edm::ParameterSet& config):
21  CandidatesProducer(name, tree, config)
22  {
23 
24  }
25 
26  virtual ~TausProducer() {}
27 
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")));
31  }
32 
33  virtual void produce(edm::Event& event, const edm::EventSetup& eventSetup) override;
34 
35 
36  private:
37  // Tokens
38  edm::EDGetTokenT<std::vector<pat::Tau>> m_taus_token;
39  edm::EDGetTokenT<std::vector<reco::GenParticle>> m_pruned_token;
40  private:
41 
42  MatchResult LeptonGenMatch(const LorentzVector& p4, const std::vector<reco::GenParticle>& genParticles)
43  {
44  static constexpr int electronPdgId = 11, muonPdgId = 13, tauPdgId = 15;
45  static constexpr double dR2_threshold = std::pow(0.2, 2);
46 
47  static const std::map<int, double> pt_thresholds = {
48  { electronPdgId, 8 }, { muonPdgId, 8 }, { tauPdgId, 15 }
49  };
50 
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 }
56  };
57 
58  MatchResult result(GenMatch::NoMatch, nullptr);
59  double match_dr2 = dR2_threshold;
60 
61 
62 
63  for(const reco::GenParticle& particle : genParticles) {
64  const bool isTauProduct = particle.statusFlags().isDirectPromptTauDecayProduct();
65  if((!particle.statusFlags().isPrompt() && !isTauProduct) || !particle.statusFlags().isLastCopy()) continue;
66 
67  const int abs_pdg = std::abs(particle.pdgId());
68  if(!pt_thresholds.count(abs_pdg)) continue;
69 
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;
72 
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;
76 
77  match_dr2 = dr2;
78  result.first = genMatches.at(pair(abs_pdg, isTauProduct));
79  result.second = &particle;
80  }
81  return result;
82  }
83 
84  inline void FindFinalStateDaughters(const reco::GenParticle& particle, std::vector<const reco::GenParticle*>& daughters,
85  const std::set<int>& pdg_to_exclude = {})
86  {
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);
91  } else {
92  for(const auto& daughter : particle.daughterRefVector())
93  FindFinalStateDaughters(*daughter, daughters, pdg_to_exclude);
94  }
95  }
96 
97  inline LorentzVector GetFinalStateMomentum(const reco::GenParticle& particle, bool excludeInvisible,
98  bool excludeLightLeptons)
99  {
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});
106 
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 },
110  };
111 
112  std::vector<const reco::GenParticle*> daughters;
113  FindFinalStateDaughters(particle, daughters, *to_exclude.at(pair(excludeInvisible, false)));
114 
115  LorentzVector p4;
116  for(auto daughter : daughters){
117  if(excludeLightLeptons && light_leptons.count(std::abs(daughter->pdgId())) && daughter->statusFlags().isDirectTauDecayProduct()) continue;
118  p4 += daughter->p4();
119  }
120  return p4;
121  }
122 
123 
124 
125  public:
126  // Tree members
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>);
131 };
132 
133 #endif
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