CMS 3D CMS Logo

BoostedTauSeedsProducer.cc
Go to the documentation of this file.
1 
2 /* =============================================================================
3  * Filename: BoostedTauSeedsProducer.cc
4  *
5  * Description: Take the two subjets found by CMSBoostedTauSeedingAlgorithm
6  * and add the data-formats for
7  * o seeding the reconstruction of hadronic taus (PFJets, collection of PFCandidates not within subjet)
8  * o computation of electron and muon isolation Pt-sums, excluding the particles in the other subjet (collection of PFCandidates within subjet, used to define "Vetos")
9  *
10  * Created: 10/22/2013 16:05:00
11  *
12  * Authors: Christian Veelken (LLR)
13  *
14  * =============================================================================
15  */
16 
24 
38 
39 #include <TMath.h>
40 
41 #include <string>
42 #include <iostream>
43 #include <iomanip>
44 
45 template <class JetType, class CandType>
47 public:
50  void produce(edm::Event&, const edm::EventSetup&) override;
51 
52 private:
53  typedef edm::AssociationMap<edm::OneToMany<std::vector<JetType>, std::vector<CandType>, unsigned int>>
55  typedef std::vector<JetType> JetTypeCollection;
56  typedef std::vector<CandType> CandTypeCollection;
57 
59 
63 
65 };
66 
67 template <class JetType, class CandType>
69  : moduleLabel_(cfg.getParameter<std::string>("@module_label")) {
70  srcSubjets_ = consumes<JetView>(cfg.getParameter<edm::InputTag>("subjetSrc"));
71  srcPFCandidates_ = consumes<CandTypeCollection>(cfg.getParameter<edm::InputTag>("pfCandidateSrc"));
72 
73  verbosity_ = (cfg.exists("verbosity")) ? cfg.getParameter<int>("verbosity") : 0;
74 
75  produces<JetTypeCollection>();
76  produces<JetToPFCandidateAssociation>("pfCandAssocMapForIsolation");
77  //produces<JetToPFCandidateAssociation>("pfCandAssocMapForIsoDepositVetos");
78 }
79 
80 namespace {
81  typedef std::vector<std::unordered_set<uint32_t>> JetToConstitMap;
82 
83  template <class JetType, class CandType>
84  JetType convertToPFJet(const reco::Jet& jet, const reco::Jet::Constituents& jetConstituents) {
85  // CV: code for filling pfJetSpecific objects taken from
86  // RecoParticleFlow/PFRootEvent/src/JetMaker.cc
87  double chargedHadronEnergy = 0.;
88  double neutralHadronEnergy = 0.;
89  double chargedEmEnergy = 0.;
90  double neutralEmEnergy = 0.;
91  double chargedMuEnergy = 0.;
92  int chargedMultiplicity = 0;
93  int neutralMultiplicity = 0;
94  int muonMultiplicity = 0;
95  for (auto const& jetConstituent : jetConstituents) {
96  const CandType* pfCandidate = dynamic_cast<const CandType*>(jetConstituent.get());
97  if (pfCandidate) {
98  switch (std::abs(pfCandidate->pdgId())) {
99  case 211: // charged hadron
100  chargedHadronEnergy += pfCandidate->energy();
101  ++chargedMultiplicity;
102  break;
103  case 11: // electron
104  chargedEmEnergy += pfCandidate->energy();
105  ++chargedMultiplicity;
106  break;
107  case 13: // muon
108  chargedMuEnergy += pfCandidate->energy();
109  ++chargedMultiplicity;
111  break;
112  case 22: // photon
113  case 2: // electromagnetic in HF
114  neutralEmEnergy += pfCandidate->energy();
115  ++neutralMultiplicity;
116  break;
117  case 130: // neutral hadron
118  case 1: // hadron in HF
119  neutralHadronEnergy += pfCandidate->energy();
120  ++neutralMultiplicity;
121  break;
122  default:
123  edm::LogWarning("convertToPFJet") << "PFCandidate: Pt = " << pfCandidate->pt()
124  << ", eta = " << pfCandidate->eta() << ", phi = " << pfCandidate->phi()
125  << " has invalid pdgID = " << pfCandidate->pdgId() << " !!" << std::endl;
126  break;
127  }
128  } else {
129  edm::LogWarning("convertToPFJet")
130  << "Jet constituent: Pt = " << jetConstituent->pt() << ", eta = " << jetConstituent->eta()
131  << ", phi = " << jetConstituent->phi() << " is not of type PFCandidate !!" << std::endl;
132  }
133  }
134  reco::PFJet::Specific pfJetSpecific;
135  pfJetSpecific.mChargedHadronEnergy = chargedHadronEnergy;
136  pfJetSpecific.mNeutralHadronEnergy = neutralHadronEnergy;
137  pfJetSpecific.mChargedEmEnergy = chargedEmEnergy;
138  pfJetSpecific.mChargedMuEnergy = chargedMuEnergy;
139  pfJetSpecific.mNeutralEmEnergy = neutralEmEnergy;
140  pfJetSpecific.mChargedMultiplicity = chargedMultiplicity;
141  pfJetSpecific.mNeutralMultiplicity = neutralMultiplicity;
142  pfJetSpecific.mMuonMultiplicity = muonMultiplicity;
143 
144  reco::PFJet pfJet(jet.p4(), jet.vertex(), pfJetSpecific, jetConstituents);
145  pfJet.setJetArea(jet.jetArea());
146 
147  return JetType(pfJet);
148  }
149 
150  void getJetConstituents(const reco::Jet& jet, reco::Jet::Constituents& jet_and_subjetConstituents) {
151  reco::Jet::Constituents jetConstituents = jet.getJetConstituents();
152  for (auto const& jetConstituent : jetConstituents) {
153  const reco::Jet* subjet = dynamic_cast<const reco::Jet*>(jetConstituent.get());
154  if (subjet) {
155  getJetConstituents(*subjet, jet_and_subjetConstituents);
156  } else {
157  jet_and_subjetConstituents.push_back(jetConstituent);
158  }
159  }
160  }
161 
162  template <class CandType>
163  std::vector<edm::Ref<std::vector<CandType>>> getPFCandidates_exclJetConstituents(
164  const reco::Jet& jet,
165  const edm::Handle<std::vector<CandType>>& pfCandidates,
166  const JetToConstitMap::value_type& constitmap,
167  bool invert) {
168  auto const& collection_cand = (*pfCandidates);
169  std::vector<edm::Ref<std::vector<CandType>>> pfCandidates_exclJetConstituents;
170  size_t numPFCandidates = pfCandidates->size();
171  for (size_t pfCandidateIdx = 0; pfCandidateIdx < numPFCandidates; ++pfCandidateIdx) {
172  if (!(deltaR2(collection_cand[pfCandidateIdx], jet) < 1.0))
173  continue;
174  bool isJetConstituent = constitmap.count(pfCandidateIdx);
175  if (!(isJetConstituent ^ invert)) {
176  edm::Ref<std::vector<CandType>> pfCandidate(pfCandidates, pfCandidateIdx);
177  pfCandidates_exclJetConstituents.push_back(pfCandidate);
178  }
179  }
180  return pfCandidates_exclJetConstituents;
181  }
182 
183  void printJetConstituents(const std::string& label, const reco::Jet::Constituents& jetConstituents) {
184  std::cout << "#" << label << " = " << jetConstituents.size() << ":" << std::endl;
185  unsigned idx = 0;
186  for (auto const& jetConstituent : jetConstituents) {
187  std::cout << " jetConstituent #" << idx << ": Pt = " << (*jetConstituent).pt()
188  << ", eta = " << (*jetConstituent).eta() << ", phi = " << (*jetConstituent).phi() << std::endl;
189  ++idx;
190  }
191  }
192 } // namespace
193 
194 template <class JetType, class CandType>
196  if (verbosity_ >= 1) {
197  std::cout << "<BoostedTauSeedsProducer::produce (moduleLabel = " << moduleLabel_ << ")>:" << std::endl;
198  }
199 
200  edm::Handle<JetView> subjets;
201  evt.getByToken(srcSubjets_, subjets);
202  if (verbosity_ >= 1) {
203  std::cout << "#subjets = " << subjets->size() << std::endl;
204  }
205  assert((subjets->size() % 2) == 0); // CV: ensure that subjets come in pairs
206 
208  evt.getByToken(srcPFCandidates_, pfCandidates);
209  if (verbosity_ >= 1) {
210  std::cout << "#pfCandidates = " << pfCandidates->size() << std::endl;
211  }
212 
213  auto selectedSubjets = std::make_unique<JetTypeCollection>();
215 
216  auto selectedSubjetPFCandidateAssociationForIsolation =
217  std::make_unique<JetToPFCandidateAssociation>(&evt.productGetter());
218  //auto selectedSubjetPFCandidateAssociationForIsoDepositVetos = std::make_unique<JetToPFCandidateAssociation>(&evt.productGetter());
219 
220  // cache for jet->pfcandidate
221  JetToConstitMap constitmap(subjets->size());
222 
223  // fill constituents map
224  const auto& thesubjets = *subjets;
225  for (unsigned i = 0; i < thesubjets.size(); ++i) {
226  for (unsigned j = 0; j < thesubjets[i].numberOfDaughters(); ++j) {
227  constitmap[i].emplace(thesubjets[i].daughterPtr(j).key());
228  }
229  }
230 
231  for (size_t idx = 0; idx < (subjets->size() / 2); ++idx) {
232  const reco::Jet* subjet1 = &subjets->at(2 * idx);
233  const reco::Jet* subjet2 = &subjets->at(2 * idx + 1);
234  assert(subjet1 && subjet2);
235  if (verbosity_ >= 1) {
236  std::cout << "processing jet #" << idx << ":" << std::endl;
237  std::cout << " subjet1: Pt = " << subjet1->pt() << ", eta = " << subjet1->eta() << ", phi = " << subjet1->phi()
238  << ", mass = " << subjet1->mass() << " (#constituents = " << subjet1->nConstituents()
239  << ", area = " << subjet1->jetArea() << ")" << std::endl;
240  std::cout << " subjet2: Pt = " << subjet2->pt() << ", eta = " << subjet2->eta() << ", phi = " << subjet2->phi()
241  << ", mass = " << subjet2->mass() << " (#constituents = " << subjet2->nConstituents()
242  << ", area = " << subjet2->jetArea() << ")" << std::endl;
243  }
244 
245  if (!(subjet1->nConstituents() >= 1 && subjet1->pt() > 1. && subjet2->nConstituents() >= 1 && subjet2->pt() > 1.))
246  continue; // CV: skip pathological cases
247 
248  // find PFCandidate constituents of each subjet
249  reco::Jet::Constituents subjetConstituents1;
250  getJetConstituents(*subjet1, subjetConstituents1);
251  reco::Jet::Constituents subjetConstituents2;
252  getJetConstituents(*subjet2, subjetConstituents2);
253  if (verbosity_ >= 1) {
254  printJetConstituents("subjetConstituents1", subjetConstituents1);
255  printJetConstituents("subjetConstituents2", subjetConstituents2);
256  }
257 
258  selectedSubjets->push_back(convertToPFJet<JetType, CandType>(*subjet1, subjetConstituents1));
259  edm::Ref<JetTypeCollection> subjetRef1(selectedSubjetRefProd, selectedSubjets->size() - 1);
260  selectedSubjets->push_back(convertToPFJet<JetType, CandType>(*subjet2, subjetConstituents2));
261  edm::Ref<JetTypeCollection> subjetRef2(selectedSubjetRefProd, selectedSubjets->size() - 1);
262 
263  // find all PFCandidates that are not constituents of the **other** subjet
264  std::vector<edm::Ref<std::vector<CandType>>> pfCandidatesNotInSubjet1 =
265  getPFCandidates_exclJetConstituents<CandType>(*subjet1, pfCandidates, constitmap[2 * idx + 1], false);
266  std::vector<edm::Ref<std::vector<CandType>>> pfCandidatesNotInSubjet2 =
267  getPFCandidates_exclJetConstituents<CandType>(*subjet2, pfCandidates, constitmap[2 * idx], false);
268  if (verbosity_ >= 1) {
269  std::cout << "#pfCandidatesNotInSubjet1 = " << pfCandidatesNotInSubjet1.size() << std::endl;
270  std::cout << "#pfCandidatesNotInSubjet2 = " << pfCandidatesNotInSubjet2.size() << std::endl;
271  }
272 
273  // build JetToPFCandidateAssociation
274  // (key = subjet, value = collection of PFCandidates that are not constituents of subjet)
275  for (auto const& pfCandidate : pfCandidatesNotInSubjet1) {
276  selectedSubjetPFCandidateAssociationForIsolation->insert(subjetRef1, pfCandidate);
277  }
278  for (auto const& pfCandidate : pfCandidatesNotInSubjet2) {
279  selectedSubjetPFCandidateAssociationForIsolation->insert(subjetRef2, pfCandidate);
280  }
281  }
282 
283  evt.put(std::move(selectedSubjets));
284  evt.put(std::move(selectedSubjetPFCandidateAssociationForIsolation), "pfCandAssocMapForIsolation");
285 }
286 
289 
GenericBoostedTauSeedsProducer< reco::PFJet, reco::PFCandidate > BoostedTauSeedsProducer
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
double pt() const final
transverse momentum
int mChargedMultiplicity
Definition: PFJet.h:72
Base class for all types of Jets.
Definition: Jet.h:20
std::vector< Constituent > Constituents
Definition: Jet.h:23
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:540
float mNeutralHadronEnergy
Definition: PFJet.h:52
float mChargedMuEnergy
Definition: PFJet.h:70
assert(be >=bs)
Jets made from PFObjects.
Definition: PFJet.h:20
float mChargedHadronEnergy
Definition: PFJet.h:51
virtual float jetArea() const
get jet area
Definition: Jet.h:103
EDProductGetter const & productGetter() const
Definition: Event.cc:106
virtual void setJetArea(float fArea)
set jet area
Definition: Jet.h:101
char const * label
float mChargedEmEnergy
Definition: PFJet.h:69
GenericBoostedTauSeedsProducer(const edm::ParameterSet &)
std::vector< CandType > CandTypeCollection
virtual int nConstituents() const
of constituents
Definition: Jet.h:65
float mNeutralEmEnergy
Definition: PFJet.h:71
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
RefProd< PROD > getRefBeforePut()
Definition: Event.h:158
void produce(edm::Event &, const edm::EventSetup &) override
edm::AssociationMap< edm::OneToMany< std::vector< JetType >, std::vector< CandType >, unsigned int > > JetToPFCandidateAssociation
int mNeutralMultiplicity
Definition: PFJet.h:73
edm::EDGetTokenT< JetView > srcSubjets_
double mass() const final
mass
Log< level::Warning, false > LogWarning
double phi() const final
momentum azimuthal angle
edm::EDGetTokenT< CandTypeCollection > srcPFCandidates_
std::vector< JetType > JetTypeCollection
GenericBoostedTauSeedsProducer< pat::Jet, pat::PackedCandidate > PATBoostedTauSeedsProducer
def move(src, dest)
Definition: eostools.py:511
double eta() const final
momentum pseudorapidity