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  ~PATObjectCrossLinker() override;
50 
51  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
52 
53 private:
54  void beginStream(edm::StreamID) override;
55  void produce(edm::Event&, const edm::EventSetup&) override;
56  void endStream() override;
57 
58  template <class C1, class C2, class C3, class C4>
59  void matchOneToMany(const C1& refProdOne,
60  C2& itemsOne,
61  const std::string& nameOne,
62  const C3& refProdMany,
63  C4& itemsMany,
64  const std::string& nameMany);
65 
66  template <class C1, class C2, class C3, class C4>
67  void matchElectronToPhoton(const C1& refProdOne,
68  C2& itemsOne,
69  const std::string& nameOne,
70  const C3& refProdMany,
71  C4& itemsMany,
72  const std::string& nameMany);
73 
74  template <class C1, class C2, class C3, class C4>
75  void matchLowPtToElectron(const C1& refProdOne,
76  C2& itemsOne,
77  const std::string& nameOne,
78  const C3& refProdMany,
79  C4& itemsMany,
80  const std::string& nameMany);
81 
82  template <class C1, class C2, class C3>
83  void matchOneToVertices(C1& itemsOne, const C2& refProdVtx, C3& itemsVtx, const std::string& nameVtx);
84 
85  template <class C1, class C2, class C3>
86  void matchVertexToMany(const C1& refProdVtx, C2& itemsVtx, const std::string& nameVtx, C3& itemsMany);
87 
88  //virtual void beginRun(edm::Run const&, edm::EventSetup const&) override;
89  //virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
90  //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
91  //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
92 
93  // ----------member data ---------------------------
105 };
106 
107 //
108 // constructors and destructor
109 //
111  : jets_(consumes<edm::View<pat::Jet>>(params.getParameter<edm::InputTag>("jets"))),
112  muons_(consumes<edm::View<pat::Muon>>(params.getParameter<edm::InputTag>("muons"))),
113  electrons_(consumes<edm::View<pat::Electron>>(params.getParameter<edm::InputTag>("electrons"))),
114  photons_(consumes<edm::View<pat::Photon>>(params.getParameter<edm::InputTag>("photons"))),
115  taus_(consumes<edm::View<pat::Tau>>(params.getParameter<edm::InputTag>("taus"))),
116  lowPtElectronsTag_(params.getParameter<edm::InputTag>("lowPtElectrons")),
117  boostedTausTag_(params.getParameter<edm::InputTag>("boostedTaus")),
118  verticesTag_(params.getParameter<edm::InputTag>("vertices")) {
119  produces<std::vector<pat::Jet>>("jets");
120  produces<std::vector<pat::Muon>>("muons");
121  produces<std::vector<pat::Electron>>("electrons");
122  produces<std::vector<pat::Photon>>("photons");
123  produces<std::vector<pat::Tau>>("taus");
124  if (!lowPtElectronsTag_.label().empty()) {
125  lowPtElectrons_ = consumes<edm::View<pat::Electron>>(lowPtElectronsTag_),
126  produces<std::vector<pat::Electron>>("lowPtElectrons");
127  }
128  if (!boostedTausTag_.label().empty()) {
129  boostedTaus_ = consumes<edm::View<pat::Tau>>(boostedTausTag_);
130  produces<std::vector<pat::Tau>>("boostedTaus");
131  }
132  if (!verticesTag_.label().empty()) {
133  vertices_ = consumes<edm::View<reco::VertexCompositePtrCandidate>>(verticesTag_);
134  produces<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
135  }
136 }
137 
139  // do anything here that needs to be done at destruction time
140  // (e.g. close files, deallocate resources etc.)
141 }
142 
143 //
144 // member functions
145 //
146 
147 // ------------ method called to produce the data ------------
148 
150 template <class C1, class C2, class C3, class C4>
151 void PATObjectCrossLinker::matchOneToMany(const C1& refProdOne,
152  C2& itemsOne,
153  const std::string& nameOne,
154  const C3& refProdMany,
155  C4& itemsMany,
156  const std::string& nameMany) {
157  size_t ji = 0;
158  for (auto& j : itemsOne) {
159  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
160  size_t mi = 0;
161  for (auto& m : itemsMany) {
162  if (matchByCommonSourceCandidatePtr(j, m) && (!m.hasUserCand(nameOne))) {
163  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
164  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
165  }
166  mi++;
167  }
168  j.setOverlaps(nameMany, overlaps);
169  ji++;
170  }
171 }
172 
173 // one electron can be matched to several photons
174 template <class C1, class C2, class C3, class C4>
176  C2& itemsOne,
177  const std::string& nameOne,
178  const C3& refProdMany,
179  C4& itemsMany,
180  const std::string& nameMany) {
181  size_t ji = 0;
182  for (auto& j : itemsOne) {
183  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
184  size_t mi = 0;
185  for (auto& m : itemsMany) {
186  if (matchByCommonParentSuperClusterRef(j, m) && (!m.hasUserCand(nameOne))) {
187  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
188  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
189  }
190  mi++;
191  }
192  j.setOverlaps(nameMany, overlaps);
193  ji++;
194  }
195 }
196 
197 // one low pt electron can be matched to several electrons
198 template <class C1, class C2, class C3, class C4>
200  C2& itemsOne,
201  const std::string& nameOne,
202  const C3& refProdMany,
203  C4& itemsMany,
204  const std::string& nameMany) {
205  size_t ji = 0;
206  for (auto& j : itemsOne) {
207  std::vector<std::pair<size_t, float>> idxs;
208  size_t mi = 0;
209  for (auto& m : itemsMany) {
210  float dr2 = deltaR2(m, j);
211  if (dr2 < 1.e-6) { // deltaR < 1.e-3
212  m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
213  idxs.push_back(std::make_pair(mi, dr2));
214  }
215  mi++;
216  }
217  std::sort(idxs.begin(), idxs.end(), [](auto& left, auto& right) { return left.second < right.second; });
218 
219  edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
220  for (auto idx : idxs) {
221  overlaps.push_back(reco::CandidatePtr(refProdMany.id(), idx.first, refProdMany.productGetter()));
222  }
223  j.setOverlaps(nameMany, overlaps);
224  ji++;
225  }
226 }
227 
228 // several vertices stored as overlap with a jet
229 // (reco vertices have no userCands)
230 template <class C1, class C2, class C3>
232  const C2& refProdVtx,
233  C3& itemsVtx,
234  const std::string& nameVtx) {
235  for (auto& j : itemsOne) {
236  edm::PtrVector<reco::Candidate> overlaps(refProdVtx.id());
237  size_t vi = 0;
238  for (auto& v : itemsVtx) {
240  overlaps.push_back(reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
241  }
242  vi++;
243  }
244  j.setOverlaps(nameVtx, overlaps);
245  }
246 }
247 
248 // vertex stored as userCand to matched object
249 // (reco vertices have no overlaps)
250 template <class C1, class C2, class C3>
251 void PATObjectCrossLinker::matchVertexToMany(const C1& refProdVtx,
252  C2& itemsVtx,
253  const std::string& nameVtx,
254  C3& itemsMany) {
255  size_t vi = 0;
256  for (auto& v : itemsVtx) {
257  for (auto& m : itemsMany) {
258  if (matchByCommonSourceCandidatePtr(v, m) && (!m.hasUserCand(nameVtx))) {
259  m.addUserCand(nameVtx, reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
260  }
261  }
262  vi++;
263  }
264 }
265 
267  using namespace edm;
268  const auto& jetsIn = iEvent.get(jets_);
269  auto jets = std::make_unique<std::vector<pat::Jet>>();
270  jets->reserve(jetsIn.size());
271  for (const auto& j : jetsIn)
272  jets->push_back(j);
273  auto jetRefProd = iEvent.getRefBeforePut<std::vector<pat::Jet>>("jets");
274 
275  const auto& muonsIn = iEvent.get(muons_);
276  auto muons = std::make_unique<std::vector<pat::Muon>>();
277  muons->reserve(muonsIn.size());
278  for (const auto& m : muonsIn)
279  muons->push_back(m);
280  auto muRefProd = iEvent.getRefBeforePut<std::vector<pat::Muon>>("muons");
281 
282  const auto& electronsIn = iEvent.get(electrons_);
283  auto electrons = std::make_unique<std::vector<pat::Electron>>();
284  electrons->reserve(electronsIn.size());
285  for (const auto& e : electronsIn)
286  electrons->push_back(e);
287  auto eleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("electrons");
288 
289  const auto& tausIn = iEvent.get(taus_);
290  auto taus = std::make_unique<std::vector<pat::Tau>>();
291  taus->reserve(tausIn.size());
292  for (const auto& t : tausIn)
293  taus->push_back(t);
294  auto tauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("taus");
295 
296  const auto& photonsIn = iEvent.get(photons_);
297  auto photons = std::make_unique<std::vector<pat::Photon>>();
298  photons->reserve(photonsIn.size());
299  for (const auto& p : photonsIn)
300  photons->push_back(p);
301  auto phRefProd = iEvent.getRefBeforePut<std::vector<pat::Photon>>("photons");
302 
303  auto lowPtElectrons = std::make_unique<std::vector<pat::Electron>>();
304  if (!lowPtElectronsTag_.label().empty()) {
305  const auto& lowPtElectronsIn = iEvent.get(lowPtElectrons_);
306  lowPtElectrons->reserve(lowPtElectronsIn.size());
307  for (const auto& e : lowPtElectronsIn) {
308  lowPtElectrons->push_back(e);
309  }
310  }
311 
312  auto boostedTaus = std::make_unique<std::vector<pat::Tau>>();
313  if (!boostedTausTag_.label().empty()) {
314  const auto& boostedTausIn = iEvent.get(boostedTaus_);
315  boostedTaus->reserve(boostedTausIn.size());
316  for (const auto& e : boostedTausIn) {
317  boostedTaus->push_back(e);
318  }
319  }
320 
321  auto vertices = std::make_unique<std::vector<reco::VertexCompositePtrCandidate>>();
322  if (!verticesTag_.label().empty()) {
323  const auto& verticesIn = iEvent.get(vertices_);
324  vertices->reserve(verticesIn.size());
325  for (const auto& e : verticesIn) {
326  vertices->push_back(e);
327  }
328  }
329 
330  matchOneToMany(jetRefProd, *jets, "jet", muRefProd, *muons, "muons");
331  matchOneToMany(jetRefProd, *jets, "jet", eleRefProd, *electrons, "electrons");
332  matchOneToMany(jetRefProd, *jets, "jet", tauRefProd, *taus, "taus");
333  matchOneToMany(jetRefProd, *jets, "jet", phRefProd, *photons, "photons");
334 
335  matchOneToMany(tauRefProd, *taus, "tau", muRefProd, *muons, "muons");
336  matchOneToMany(tauRefProd, *taus, "tau", eleRefProd, *electrons, "electrons");
337 
338  matchElectronToPhoton(eleRefProd, *electrons, "electron", phRefProd, *photons, "photons");
339 
340  if (!lowPtElectronsTag_.label().empty()) {
341  auto lowPtEleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("lowPtElectrons");
342  matchLowPtToElectron(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", eleRefProd, *electrons, "electrons");
343  matchElectronToPhoton(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", phRefProd, *photons, "photons");
344  }
345 
346  if (!boostedTausTag_.label().empty()) {
347  auto boostedTauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("boostedTaus");
348  matchOneToMany(jetRefProd, *jets, "jet", boostedTauRefProd, *boostedTaus, "boostedTaus");
349  }
350 
351  if (!verticesTag_.label().empty()) {
352  auto vtxRefProd = iEvent.getRefBeforePut<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
353  matchOneToVertices(*jets, vtxRefProd, *vertices, "vertices");
354  matchOneToVertices(*taus, vtxRefProd, *vertices, "vertices");
355  matchVertexToMany(vtxRefProd, *vertices, "vertex", *muons);
356  matchVertexToMany(vtxRefProd, *vertices, "vertex", *electrons);
357  }
358 
359  iEvent.put(std::move(jets), "jets");
360  iEvent.put(std::move(muons), "muons");
361  iEvent.put(std::move(electrons), "electrons");
362  iEvent.put(std::move(taus), "taus");
363  iEvent.put(std::move(photons), "photons");
364  if (!lowPtElectronsTag_.label().empty())
365  iEvent.put(std::move(lowPtElectrons), "lowPtElectrons");
366  if (!boostedTausTag_.label().empty())
367  iEvent.put(std::move(boostedTaus), "boostedTaus");
368  if (!verticesTag_.label().empty())
369  iEvent.put(std::move(vertices), "vertices");
370 }
371 
372 // ------------ method called once each stream before processing any runs, lumis or events ------------
374 
375 // ------------ method called once each stream after processing all runs, lumis and events ------------
377 
378 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
381  desc.add<edm::InputTag>("jets")->setComment("a jet collection derived from pat::Jet");
382  desc.add<edm::InputTag>("muons")->setComment("a muon collection derived from pat::Muon");
383  desc.add<edm::InputTag>("electrons")->setComment("an electron collection derived from pat::Electron");
384  desc.add<edm::InputTag>("photons")->setComment("a photon collection derived from pat::Photon");
385  desc.add<edm::InputTag>("taus")->setComment("a tau collection derived from pat::Tau");
386  desc.add<edm::InputTag>("lowPtElectrons", edm::InputTag(""))
387  ->setComment("an optional electron collection derived from pat::Electron, empty=>not used");
388  desc.add<edm::InputTag>("boostedTaus", edm::InputTag(""))
389  ->setComment("an optional boosted tau collection derived from pat::Tau, empty=>not used");
390  desc.add<edm::InputTag>("vertices", edm::InputTag(""))
391  ->setComment("an optional vertex collection derived from reco::VertexCompositePtrCandidate,empty=>not used");
392  descriptions.add("patObjectCrossLinker", desc);
393 }
394 
395 //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 beginStream(edm::StreamID) 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
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