CMS 3D CMS Logo

PATObjectCrossLinker.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PhysicsTools/NanoAOD
4 // Class: PATObjectCrossLinker
5 //
13 //
14 // Original Author: Andrea Rizzi
15 // Created: Mon, 28 Aug 2017 09:26:39 GMT
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
25 
28 
31 
38 
40 
42 //
43 // class declaration
44 //
45 
47 public:
48  explicit PATObjectCrossLinker(const edm::ParameterSet&);
49 
50  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
51 
52 private:
53  void produce(edm::Event&, const edm::EventSetup&) override;
54 
55  template <class C1, class C2, class C3, class C4>
56  void matchOneToMany(const C1& refProdOne,
57  C2& itemsOne,
58  const std::string& nameOne,
59  const C3& refProdMany,
60  C4& itemsMany,
61  const std::string& nameMany);
62 
63  template <class C1, class C2, class C3, class C4>
64  void matchElectronToPhoton(const C1& refProdOne,
65  C2& itemsOne,
66  const std::string& nameOne,
67  const C3& refProdMany,
68  C4& itemsMany,
69  const std::string& nameMany);
70 
71  template <class C1, class C2, class C3, class C4>
72  void matchLowPtToElectron(const C1& refProdOne,
73  C2& itemsOne,
74  const std::string& nameOne,
75  const C3& refProdMany,
76  C4& itemsMany,
77  const std::string& nameMany);
78 
79  template <class C1, class C2, class C3>
80  void matchOneToVertices(C1& itemsOne, const C2& refProdVtx, C3& itemsVtx, const std::string& nameVtx);
81 
82  template <class C1, class C2, class C3>
83  void matchVertexToMany(const C1& refProdVtx, C2& itemsVtx, const std::string& nameVtx, C3& itemsMany);
84 
85  // ----------member data ---------------------------
97 };
98 
99 //
100 // constructors and destructor
101 //
103  : jets_(consumes<edm::View<pat::Jet>>(params.getParameter<edm::InputTag>("jets"))),
104  muons_(consumes<edm::View<pat::Muon>>(params.getParameter<edm::InputTag>("muons"))),
105  electrons_(consumes<edm::View<pat::Electron>>(params.getParameter<edm::InputTag>("electrons"))),
106  photons_(consumes<edm::View<pat::Photon>>(params.getParameter<edm::InputTag>("photons"))),
107  taus_(consumes<edm::View<pat::Tau>>(params.getParameter<edm::InputTag>("taus"))),
108  lowPtElectronsTag_(params.getParameter<edm::InputTag>("lowPtElectrons")),
109  boostedTausTag_(params.getParameter<edm::InputTag>("boostedTaus")),
110  verticesTag_(params.getParameter<edm::InputTag>("vertices")) {
111  produces<std::vector<pat::Jet>>("jets");
112  produces<std::vector<pat::Muon>>("muons");
113  produces<std::vector<pat::Electron>>("electrons");
114  produces<std::vector<pat::Photon>>("photons");
115  produces<std::vector<pat::Tau>>("taus");
116  if (!lowPtElectronsTag_.label().empty()) {
117  lowPtElectrons_ = consumes<edm::View<pat::Electron>>(lowPtElectronsTag_),
118  produces<std::vector<pat::Electron>>("lowPtElectrons");
119  }
120  if (!boostedTausTag_.label().empty()) {
121  boostedTaus_ = consumes<edm::View<pat::Tau>>(boostedTausTag_);
122  produces<std::vector<pat::Tau>>("boostedTaus");
123  }
124  if (!verticesTag_.label().empty()) {
125  vertices_ = consumes<edm::View<reco::VertexCompositePtrCandidate>>(verticesTag_);
126  produces<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
127  }
128 }
129 
130 //
131 // member functions
132 //
133 
134 // ------------ method called to produce the data ------------
135 
137 template <class C1, class C2, class C3, class C4>
138 void PATObjectCrossLinker::matchOneToMany(const C1& refProdOne,
139  C2& itemsOne,
140  const std::string& nameOne,
141  const C3& refProdMany,
142  C4& itemsMany,
143  const std::string& nameMany) {
144  size_t ji = 0;
145  for (auto& j : itemsOne) {
146  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
147  size_t mi = 0;
148  for (auto& m : itemsMany) {
149  if (matchByCommonSourceCandidatePtr(j, m) && (!m.hasUserCand(nameOne))) {
150  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
151  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
152  }
153  mi++;
154  }
155  j.setOverlaps(nameMany, overlaps);
156  ji++;
157  }
158 }
159 
160 // one electron can be matched to several photons
161 template <class C1, class C2, class C3, class C4>
163  C2& itemsOne,
164  const std::string& nameOne,
165  const C3& refProdMany,
166  C4& itemsMany,
167  const std::string& nameMany) {
168  size_t ji = 0;
169  for (auto& j : itemsOne) {
170  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
171  size_t mi = 0;
172  for (auto& m : itemsMany) {
173  if (matchByCommonParentSuperClusterRef(j, m) && (!m.hasUserCand(nameOne))) {
174  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
175  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
176  }
177  mi++;
178  }
179  j.setOverlaps(nameMany, overlaps);
180  ji++;
181  }
182 }
183 
184 // one low pt electron can be matched to several electrons
185 template <class C1, class C2, class C3, class C4>
187  C2& itemsOne,
188  const std::string& nameOne,
189  const C3& refProdMany,
190  C4& itemsMany,
191  const std::string& nameMany) {
192  size_t ji = 0;
193  for (auto& j : itemsOne) {
194  std::vector<std::pair<size_t, float>> idxs;
195  size_t mi = 0;
196  for (auto& m : itemsMany) {
197  float dr2 = deltaR2(m, j);
198  if (dr2 < 1.e-6) { // deltaR < 1.e-3
199  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
200  idxs.push_back(std::make_pair(mi, dr2));
201  }
202  mi++;
203  }
204  std::sort(idxs.begin(), idxs.end(), [](auto& left, auto& right) { return left.second < right.second; });
205 
206  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
207  for (auto idx : idxs) {
208  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), idx.first, refProdMany.productGetter()));
209  }
210  j.setOverlaps(nameMany, overlaps);
211  ji++;
212  }
213 }
214 
215 // several vertices stored as overlap with a jet
216 // (reco vertices have no userCands)
217 template <class C1, class C2, class C3>
219  const C2& refProdVtx,
220  C3& itemsVtx,
221  const std::string& nameVtx) {
222  for (auto& j : itemsOne) {
223  edm::PtrVector<reco::Candidate> overlaps(refProdVtx.id());
224  size_t vi = 0;
225  for (auto& v : itemsVtx) {
227  overlaps.push_back(reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
228  }
229  vi++;
230  }
231  j.setOverlaps(nameVtx, overlaps);
232  }
233 }
234 
235 // vertex stored as userCand to matched object
236 // (reco vertices have no overlaps)
237 template <class C1, class C2, class C3>
238 void PATObjectCrossLinker::matchVertexToMany(const C1& refProdVtx,
239  C2& itemsVtx,
240  const std::string& nameVtx,
241  C3& itemsMany) {
242  size_t vi = 0;
243  for (auto& v : itemsVtx) {
244  for (auto& m : itemsMany) {
245  if (matchByCommonSourceCandidatePtr(v, m) && (!m.hasUserCand(nameVtx))) {
246  m.addUserCand(nameVtx, reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
247  }
248  }
249  vi++;
250  }
251 }
252 
254  using namespace edm;
255  const auto& jetsIn = iEvent.get(jets_);
256  auto jets = std::make_unique<std::vector<pat::Jet>>();
257  jets->reserve(jetsIn.size());
258  for (const auto& j : jetsIn)
259  jets->push_back(j);
260  auto jetRefProd = iEvent.getRefBeforePut<std::vector<pat::Jet>>("jets");
261 
262  const auto& muonsIn = iEvent.get(muons_);
263  auto muons = std::make_unique<std::vector<pat::Muon>>();
264  muons->reserve(muonsIn.size());
265  for (const auto& m : muonsIn)
266  muons->push_back(m);
267  auto muRefProd = iEvent.getRefBeforePut<std::vector<pat::Muon>>("muons");
268 
269  const auto& electronsIn = iEvent.get(electrons_);
270  auto electrons = std::make_unique<std::vector<pat::Electron>>();
271  electrons->reserve(electronsIn.size());
272  for (const auto& e : electronsIn)
273  electrons->push_back(e);
274  auto eleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("electrons");
275 
276  const auto& tausIn = iEvent.get(taus_);
277  auto taus = std::make_unique<std::vector<pat::Tau>>();
278  taus->reserve(tausIn.size());
279  for (const auto& t : tausIn)
280  taus->push_back(t);
281  auto tauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("taus");
282 
283  const auto& photonsIn = iEvent.get(photons_);
284  auto photons = std::make_unique<std::vector<pat::Photon>>();
285  photons->reserve(photonsIn.size());
286  for (const auto& p : photonsIn)
287  photons->push_back(p);
288  auto phRefProd = iEvent.getRefBeforePut<std::vector<pat::Photon>>("photons");
289 
290  auto lowPtElectrons = std::make_unique<std::vector<pat::Electron>>();
291  if (!lowPtElectronsTag_.label().empty()) {
292  const auto& lowPtElectronsIn = iEvent.get(lowPtElectrons_);
293  lowPtElectrons->reserve(lowPtElectronsIn.size());
294  for (const auto& e : lowPtElectronsIn) {
295  lowPtElectrons->push_back(e);
296  }
297  }
298 
299  auto boostedTaus = std::make_unique<std::vector<pat::Tau>>();
300  if (!boostedTausTag_.label().empty()) {
301  const auto& boostedTausIn = iEvent.get(boostedTaus_);
302  boostedTaus->reserve(boostedTausIn.size());
303  for (const auto& e : boostedTausIn) {
304  boostedTaus->push_back(e);
305  }
306  }
307 
308  auto vertices = std::make_unique<std::vector<reco::VertexCompositePtrCandidate>>();
309  if (!verticesTag_.label().empty()) {
310  const auto& verticesIn = iEvent.get(vertices_);
311  vertices->reserve(verticesIn.size());
312  for (const auto& e : verticesIn) {
313  vertices->push_back(e);
314  }
315  }
316 
317  matchOneToMany(jetRefProd, *jets, "jet", muRefProd, *muons, "muons");
318  matchOneToMany(jetRefProd, *jets, "jet", eleRefProd, *electrons, "electrons");
319  matchOneToMany(jetRefProd, *jets, "jet", tauRefProd, *taus, "taus");
320  matchOneToMany(jetRefProd, *jets, "jet", phRefProd, *photons, "photons");
321 
322  matchOneToMany(tauRefProd, *taus, "tau", muRefProd, *muons, "muons");
323  matchOneToMany(tauRefProd, *taus, "tau", eleRefProd, *electrons, "electrons");
324 
325  matchElectronToPhoton(eleRefProd, *electrons, "electron", phRefProd, *photons, "photons");
326 
327  if (!lowPtElectronsTag_.label().empty()) {
328  auto lowPtEleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("lowPtElectrons");
329  matchLowPtToElectron(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", eleRefProd, *electrons, "electrons");
330  matchElectronToPhoton(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", phRefProd, *photons, "photons");
331  }
332 
333  if (!boostedTausTag_.label().empty()) {
334  auto boostedTauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("boostedTaus");
335  matchOneToMany(jetRefProd, *jets, "jet", boostedTauRefProd, *boostedTaus, "boostedTaus");
336  }
337 
338  if (!verticesTag_.label().empty()) {
339  auto vtxRefProd = iEvent.getRefBeforePut<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
340  matchOneToVertices(*jets, vtxRefProd, *vertices, "vertices");
341  matchOneToVertices(*taus, vtxRefProd, *vertices, "vertices");
342  matchVertexToMany(vtxRefProd, *vertices, "vertex", *muons);
343  matchVertexToMany(vtxRefProd, *vertices, "vertex", *electrons);
344  }
345 
346  iEvent.put(std::move(jets), "jets");
347  iEvent.put(std::move(muons), "muons");
348  iEvent.put(std::move(electrons), "electrons");
349  iEvent.put(std::move(taus), "taus");
350  iEvent.put(std::move(photons), "photons");
351  if (!lowPtElectronsTag_.label().empty())
352  iEvent.put(std::move(lowPtElectrons), "lowPtElectrons");
353  if (!boostedTausTag_.label().empty())
354  iEvent.put(std::move(boostedTaus), "boostedTaus");
355  if (!verticesTag_.label().empty())
356  iEvent.put(std::move(vertices), "vertices");
357 }
358 
359 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
362  desc.add<edm::InputTag>("jets")->setComment("a jet collection derived from pat::Jet");
363  desc.add<edm::InputTag>("muons")->setComment("a muon collection derived from pat::Muon");
364  desc.add<edm::InputTag>("electrons")->setComment("an electron collection derived from pat::Electron");
365  desc.add<edm::InputTag>("photons")->setComment("a photon collection derived from pat::Photon");
366  desc.add<edm::InputTag>("taus")->setComment("a tau collection derived from pat::Tau");
367  desc.add<edm::InputTag>("lowPtElectrons", edm::InputTag(""))
368  ->setComment("an optional electron collection derived from pat::Electron, empty=>not used");
369  desc.add<edm::InputTag>("boostedTaus", edm::InputTag(""))
370  ->setComment("an optional boosted tau collection derived from pat::Tau, empty=>not used");
371  desc.add<edm::InputTag>("vertices", edm::InputTag(""))
372  ->setComment("an optional vertex collection derived from reco::VertexCompositePtrCandidate,empty=>not used");
373  descriptions.add("patObjectCrossLinker", desc);
374 }
375 
376 //define this as a plug-in
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void matchOneToMany(const C1 &refProdOne, C2 &itemsOne, const std::string &nameOne, const C3 &refProdMany, C4 &itemsMany, const std::string &nameMany)
Definition: Photon.py:1
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: PtrVectorBase.h:63
void produce(edm::Event &, const edm::EventSetup &) override
void matchOneToVertices(C1 &itemsOne, const C2 &refProdVtx, C3 &itemsVtx, const std::string &nameVtx)
const edm::EDGetTokenT< edm::View< pat::Muon > > muons_
std::string const & label() const
Definition: InputTag.h:36
bool matchByCommonParentSuperClusterRef(const C1 &c1, const C2 &c2)
Definition: MatchingUtils.h:21
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:214
edm::EDGetTokenT< edm::View< pat::Electron > > lowPtElectrons_
boostedTaus
Definition: nano_cff.py:44
Definition: HeavyIon.h:7
void matchVertexToMany(const C1 &refProdVtx, C2 &itemsVtx, const std::string &nameVtx, C3 &itemsMany)
lowPtElectrons
Definition: nano_cff.py:42
int iEvent
Definition: GenABIO.cc:224
PATObjectCrossLinker(const edm::ParameterSet &)
edm::EDGetTokenT< edm::View< pat::Tau > > boostedTaus_
bool matchByCommonSourceCandidatePtr(const C1 &c1, const C2 &c2)
Definition: MatchingUtils.h:9
Definition: Muon.py:1
Definition: Jet.py:1
const edm::EDGetTokenT< edm::View< pat::Jet > > jets_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const edm::EDGetTokenT< edm::View< pat::Electron > > electrons_
void matchElectronToPhoton(const C1 &refProdOne, C2 &itemsOne, const std::string &nameOne, const C3 &refProdMany, C4 &itemsMany, const std::string &nameMany)
Definition: Tau.py:1
void matchLowPtToElectron(const C1 &refProdOne, C2 &itemsOne, const std::string &nameOne, const C3 &refProdMany, C4 &itemsMany, const std::string &nameMany)
edm::InputTag lowPtElectronsTag_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< edm::View< reco::VertexCompositePtrCandidate > > vertices_
const edm::EDGetTokenT< edm::View< pat::Tau > > taus_
HLT enums.
const edm::EDGetTokenT< edm::View< pat::Photon > > photons_
def move(src, dest)
Definition: eostools.py:511