CMS 3D CMS Logo

MuonSimClassifier.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SimMuon/MCTruth
4 // Class: MuonSimClassifier
5 //
6 /*
7 
8 
9  CLASSIFICATION: For each RECO Muon, match to SIM particle, and then:
10  - If the SIM is not a Muon, label as Punchthrough (1) except if it is an
11  electron or positron (11)
12  - If the SIM is a Muon, then look at it's provenance.
13  A) the SIM muon is also a GEN muon, whose parent is NOT A HADRON AND NOT A
14  TAU
15  -> classify as "primary" (4).
16  B) the SIM muon is also a GEN muon, whose parent is HEAVY FLAVOURED HADRON
17  OR A TAU
18  -> classify as "heavy flavour" (3)
19  C) classify as "light flavour/decay" (2)
20 
21  In any case, if the TP is not preferentially matched back to the same RECO
22  muon, label as Ghost (flip the classification)
23 
24 
25  FLAVOUR:
26  - for non-muons: 0
27  - for primary muons: 13
28  - for non primary muons: flavour of the mother: std::abs(pdgId) of heaviest
29  quark, or 15 for tau
30 
31 */
32 //
33 // Original Author: G.Petrucciani and G.Abbiendi
34 // Created: Sun Nov 16 16:14:09 CET 2008
35 // revised: 3/Aug/2017
36 //
37 
38 // system include files
39 #include <memory>
40 #include <set>
41 
42 // user include files
45 
50 
52 
56 
61 
65 
67 
68 //
69 // class decleration
71 public:
72  explicit MuonSimClassifier(const edm::ParameterSet &);
73  ~MuonSimClassifier() override;
74 
75 private:
76  void produce(edm::Event &, const edm::EventSetup &) override;
79 
82 
85 
89 
92 
97 
99  int flavour(int pdgId) const;
100 
102  template <typename T>
105  const std::vector<T> &values,
106  const std::string &label) const;
107 
109  if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
110  return tp->parentVertex()->sourceTracks()[0];
111  } else {
112  return TrackingParticleRef();
113  }
114  }
115 
119  int convertAndPush(const TrackingParticle &tp,
121  const TrackingParticleRef &momRef,
123 };
124 
126  : muonsToken_(consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("muons"))),
128  consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
130  consumes<reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::InputTag>("associatorLabel"))),
131  decayRho_(iConfig.getParameter<double>("decayRho")),
132  decayAbsZ_(iConfig.getParameter<double>("decayAbsZ")),
133  linkToGenParticles_(iConfig.getParameter<bool>("linkToGenParticles")),
134  genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::InputTag>("genParticles") : edm::InputTag())
135 
136 {
137  std::string trackType = iConfig.getParameter<std::string>("trackType");
138  if (trackType == "inner")
140  else if (trackType == "outer")
142  else if (trackType == "global")
144  else if (trackType == "segments")
146  else if (trackType == "glb_or_trk")
148  else
149  throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
150  if (linkToGenParticles_) {
151  genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
152  }
153 
154  produces<edm::ValueMap<reco::MuonSimInfo>>();
155  if (linkToGenParticles_) {
156  produces<reco::GenParticleCollection>("secondaries");
157  produces<edm::Association<reco::GenParticleCollection>>("toPrimaries");
158  produces<edm::Association<reco::GenParticleCollection>>("toSecondaries");
159  }
160 }
161 
163 
164 void dumpFormatedInfo(const reco::MuonSimInfo &simInfo) {
165  return;
166  LogTrace("MuonSimClassifier") << "\t Particle pdgId = " << simInfo.pdgId << ", (Event,Bx) = "
167  << "(" << simInfo.tpEvent << "," << simInfo.tpBX << ")"
168  << "\n\t q*p = " << simInfo.charge * simInfo.p4.P() << ", pT = " << simInfo.p4.pt()
169  << ", eta = " << simInfo.p4.eta() << ", phi = " << simInfo.p4.phi()
170  << "\n\t produced at vertex rho = " << simInfo.vertex.Rho()
171  << ", z = " << simInfo.vertex.Z() << ", (GEANT4 process = " << simInfo.g4processType
172  << ")\n";
173 }
174 
177  iEvent.getByToken(muonsToken_, muons);
178 
180  iEvent.getByToken(trackingParticlesToken_, trackingParticles);
181 
183  if (linkToGenParticles_) {
184  iEvent.getByToken(genParticlesToken_, genParticles);
185  }
186 
188  iEvent.getByToken(muAssocToken_, associatorBase);
189  const reco::MuonToTrackingParticleAssociator *assoByHits = associatorBase.product();
190 
191  reco::MuonToSimCollection recSimColl;
192  reco::SimToMuonCollection simRecColl;
193  LogTrace("MuonSimClassifier") << "\n "
194  "***************************************************************** ";
195  LogTrace("MuonSimClassifier") << " RECO MUON association, type: " << trackType_;
196  LogTrace("MuonSimClassifier") << " ******************************************"
197  "*********************** \n";
198 
200  for (size_t i = 0, n = muons->size(); i < n; ++i) {
201  allMuons.push_back(muons->refAt(i));
202  }
203 
205  for (size_t i = 0, n = trackingParticles->size(); i < n; ++i) {
206  allTPs.push_back(TrackingParticleRef(trackingParticles, i));
207  }
208 
209  assoByHits->associateMuons(recSimColl, simRecColl, allMuons, trackType_, allTPs);
210 
211  // for global muons without hits on muon detectors, look at the linked
212  // standalone muon
213  reco::MuonToSimCollection updSTA_recSimColl;
214  reco::SimToMuonCollection updSTA_simRecColl;
215  if (trackType_ == reco::GlobalTk) {
216  LogTrace("MuonSimClassifier") << "\n "
217  "***************************************************************** ";
218  LogTrace("MuonSimClassifier") << " STANDALONE (UpdAtVtx) MUON association ";
219  LogTrace("MuonSimClassifier") << " ****************************************"
220  "************************* \n";
221  assoByHits->associateMuons(updSTA_recSimColl, updSTA_simRecColl, allMuons, reco::OuterTk, allTPs);
222  }
223 
224  typedef reco::MuonToSimCollection::const_iterator r2s_it;
225  typedef reco::SimToMuonCollection::const_iterator s2r_it;
226 
227  size_t nmu = muons->size();
228  LogTrace("MuonSimClassifier") << "\n There are " << nmu << " reco::Muons.";
229 
230  std::vector<reco::MuonSimInfo> simInfo;
231 
232  std::unique_ptr<reco::GenParticleCollection> secondaries; // output collection of secondary muons
233  std::map<TrackingParticleRef, int> tpToSecondaries; // map from tp to (index+1) in output collection
234  std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu,
235  -1); // map from input into (index) in output, -1 for null
237  secondaries.reset(new reco::GenParticleCollection());
238 
239  // loop on reco muons
240  for (size_t i = 0; i < nmu; ++i) {
241  simInfo.push_back(reco::MuonSimInfo());
242  LogTrace("MuonSimClassifier") << "\n reco::Muon # " << i;
243 
245  edm::RefToBase<reco::Muon> muMatchBack;
246  r2s_it match = recSimColl.find(allMuons.at(i));
247  s2r_it matchback;
248  if (match != recSimColl.end()) {
249  // match->second is vector, front is first element, first is the ref
250  // (second would be the quality)
251  tp = match->second.front().first;
252  simInfo[i].tpId = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
253  simInfo[i].tpAssoQuality = match->second.front().second;
254  s2r_it matchback = simRecColl.find(tp);
255  if (matchback != simRecColl.end()) {
256  muMatchBack = matchback->second.front().first;
257  } else {
258  LogTrace("MuonSimClassifier") << "\n***WARNING: This I do NOT understand: why no match back? "
259  "*** \n";
260  }
261  } else {
262  if ((trackType_ == reco::GlobalTk) && allMuons.at(i)->isGlobalMuon()) {
263  // perform a second attempt, matching with the standalone muon
264  r2s_it matchSta = updSTA_recSimColl.find(allMuons.at(i));
265  if (matchSta != updSTA_recSimColl.end()) {
266  tp = matchSta->second.front().first;
267  simInfo[i].tpId = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs
268  // should not appear here at all
269  simInfo[i].tpAssoQuality = matchSta->second.front().second;
270  s2r_it matchback = updSTA_simRecColl.find(tp);
271  if (matchback != updSTA_simRecColl.end()) {
272  muMatchBack = matchback->second.front().first;
273  } else {
274  LogTrace("MuonSimClassifier") << "\n***WARNING: This I do NOT understand: why no match back "
275  "in updSTA? *** \n";
276  }
277  }
278  } else {
279  LogTrace("MuonSimClassifier") << "\t No matching TrackingParticle is found ";
280  }
281  }
282 
283  if (tp.isNonnull()) {
284  bool isGhost = muMatchBack != allMuons.at(i);
285  if (isGhost)
286  LogTrace("MuonSimClassifier") << "\t *** This seems a Duplicate muon ! "
287  "classif[i] will be < 0 ***";
288 
289  // identify signal and pileup TP
290  simInfo[i].tpBX = tp->eventId().bunchCrossing();
291  simInfo[i].tpEvent = tp->eventId().event();
292 
293  simInfo[i].pdgId = tp->pdgId();
294  simInfo[i].vertex = tp->vertex();
295 
296  // added info on GEANT process producing the TrackingParticle
297  const std::vector<SimVertex> &g4Vs = tp->parentVertex()->g4Vertices();
298  simInfo[i].g4processType = g4Vs[0].processType();
299 
300  simInfo[i].charge = tp->charge();
301  simInfo[i].p4 = tp->p4();
302 
303  // Try to extract mother and grand mother of this muon.
304  // Unfortunately, SIM and GEN histories require diffent code :-(
305  if (!tp->genParticles().empty()) { // Muon is in GEN
306  reco::GenParticleRef genp = tp->genParticles()[0];
307  reco::GenParticleRef genMom = genp->numberOfMothers() > 0 ? genp->motherRef() : reco::GenParticleRef();
308  reco::GenParticleRef mMom = genMom;
309 
310  if (genMom.isNonnull()) {
311  if (genMom->pdgId() != tp->pdgId()) {
312  simInfo[i].motherPdgId = genMom->pdgId();
313  simInfo[i].motherStatus = genMom->status();
314  simInfo[i].motherVertex = genMom->vertex();
315  } else {
316  // if mother has the same identity look backwards for the real
317  // mother (it may happen in radiative decays)
318  int jm = 0;
319  while (mMom->pdgId() == tp->pdgId()) {
320  jm++;
321  if (mMom->numberOfMothers() > 0) {
322  mMom = mMom->motherRef();
323  } else {
324  LogTrace("MuonSimClassifier") << "\t No Mother is found ";
325  break;
326  }
327 
328  LogTrace("MuonSimClassifier") << "\t\t backtracking mother " << jm << ", pdgId = " << mMom->pdgId()
329  << ", status= " << mMom->status();
330  }
331  genMom = mMom; // redefine genMom
332  simInfo[i].motherPdgId = genMom->pdgId();
333  simInfo[i].motherStatus = genMom->status();
334  simInfo[i].motherVertex = genMom->vertex();
335  }
336  dumpFormatedInfo(simInfo[i]);
337  LogTrace("MuonSimClassifier") << "\t has GEN mother pdgId = " << simInfo[i].motherPdgId
338  << " (status = " << simInfo[i].motherStatus << ")";
339 
340  reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
341 
342  if (genGMom.isNonnull()) {
343  simInfo[i].grandMotherPdgId = genGMom->pdgId();
344  LogTrace("MuonSimClassifier")
345  << "\t\t mother prod. vertex rho = " << simInfo[i].motherVertex.Rho()
346  << ", z = " << simInfo[i].motherVertex.Z() << ", grand-mom pdgId = " << simInfo[i].grandMotherPdgId;
347  }
348  // in this case, we might want to know the heaviest mom flavour
349  for (reco::GenParticleRef nMom = genMom;
350  nMom.isNonnull() && std::abs(nMom->pdgId()) >= 100; // stop when we're no longer
351  // looking at hadrons or mesons
352  nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
353  int flav = flavour(nMom->pdgId());
354  if (simInfo[i].heaviestMotherFlavour < flav)
355  simInfo[i].heaviestMotherFlavour = flav;
356  LogTrace("MuonSimClassifier")
357  << "\t\t backtracking flavour: mom pdgId = " << nMom->pdgId() << ", flavour = " << flav
358  << ", heaviest so far = " << simInfo[i].heaviestMotherFlavour;
359  }
360  } else { // mother is null ??
361  dumpFormatedInfo(simInfo[i]);
362  LogTrace("MuonSimClassifier") << "\t has NO mother!";
363  }
364  } else { // Muon is in SIM Only
365  TrackingParticleRef simMom = getTpMother(tp);
366  if (simMom.isNonnull()) {
367  simInfo[i].motherPdgId = simMom->pdgId();
368  simInfo[i].motherVertex = simMom->vertex();
369  dumpFormatedInfo(simInfo[i]);
370  LogTrace("MuonSimClassifier") << "\t has SIM mother pdgId = " << simInfo[i].motherPdgId
371  << " produced at rho = " << simMom->vertex().Rho()
372  << ", z = " << simMom->vertex().Z();
373 
374  if (!simMom->genParticles().empty()) {
375  simInfo[i].motherStatus = simMom->genParticles()[0]->status();
376  reco::GenParticleRef genGMom =
377  (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
379  if (genGMom.isNonnull())
380  simInfo[i].grandMotherPdgId = genGMom->pdgId();
381  LogTrace("MuonSimClassifier") << "\t\t SIM mother is in GEN (status " << simInfo[i].motherStatus
382  << "), grand-mom id = " << simInfo[i].grandMotherPdgId;
383  } else {
384  simInfo[i].motherStatus = -1;
385  TrackingParticleRef simGMom = getTpMother(simMom);
386  if (simGMom.isNonnull())
387  simInfo[i].grandMotherPdgId = simGMom->pdgId();
388  LogTrace("MuonSimClassifier")
389  << "\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[i].grandMotherPdgId;
390  }
391  } else {
392  dumpFormatedInfo(simInfo[i]);
393  LogTrace("MuonSimClassifier") << "\t has NO mother!";
394  }
395  }
396  simInfo[i].motherFlavour = flavour(simInfo[i].motherPdgId);
397  simInfo[i].grandMotherFlavour = flavour(simInfo[i].grandMotherPdgId);
398 
399  // Check first IF this is a muon at all
400  if (std::abs(tp->pdgId()) != 13) {
401  if (std::abs(tp->pdgId()) == 11) {
402  simInfo[i].primaryClass = isGhost ? reco::MuonSimType::GhostElectron : reco::MuonSimType::MatchedElectron;
403  simInfo[i].extendedClass =
405  LogTrace("MuonSimClassifier") << "\t This is electron/positron. classif[i] = " << simInfo[i].primaryClass;
406  } else {
407  simInfo[i].primaryClass =
409  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::ExtGhostPunchthrough
411  LogTrace("MuonSimClassifier") << "\t This is not a muon. Sorry. classif[i] = " << simInfo[i].primaryClass;
412  }
413  continue;
414  }
415 
416  // Is this SIM muon also a GEN muon, with a mother?
417  if (!tp->genParticles().empty() && (simInfo[i].motherPdgId != 0)) {
418  if (std::abs(simInfo[i].motherPdgId) < 100 && (std::abs(simInfo[i].motherPdgId) != 15)) {
419  simInfo[i].primaryClass =
421  simInfo[i].flavour = 13;
422  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromGaugeOrHiggsBoson
424  LogTrace("MuonSimClassifier") << "\t This seems PRIMARY MUON ! classif[i] = " << simInfo[i].primaryClass;
425  } else if (simInfo[i].motherFlavour == 4 || simInfo[i].motherFlavour == 5 || simInfo[i].motherFlavour == 15) {
426  simInfo[i].primaryClass =
428  simInfo[i].flavour = simInfo[i].motherFlavour;
429  if (simInfo[i].motherFlavour == 15)
430  simInfo[i].extendedClass =
432  else if (simInfo[i].motherFlavour == 5)
433  simInfo[i].extendedClass =
435  else if (simInfo[i].heaviestMotherFlavour == 5)
436  simInfo[i].extendedClass =
438  else
439  simInfo[i].extendedClass =
441  LogTrace("MuonSimClassifier") << "\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
442  } else {
443  simInfo[i].primaryClass =
445  simInfo[i].flavour = simInfo[i].motherFlavour;
446  LogTrace("MuonSimClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
447  }
448  } else {
449  simInfo[i].primaryClass =
451  simInfo[i].flavour = simInfo[i].motherFlavour;
452  LogTrace("MuonSimClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
453  }
454 
455  // extended classification
456  // don't we override previous decisions?
457  if (simInfo[i].motherPdgId == 0)
458  // if it has no mom, it's not a primary particle so it won't be in ppMuX
459  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromNonPrimaryParticle
461  else if (std::abs(simInfo[i].motherPdgId) < 100) {
462  if (simInfo[i].motherFlavour == 15)
463  simInfo[i].extendedClass =
465  else
466  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromGaugeOrHiggsBoson
468  } else if (simInfo[i].motherFlavour == 5)
469  simInfo[i].extendedClass =
471  else if (simInfo[i].motherFlavour == 4) {
472  if (simInfo[i].heaviestMotherFlavour == 5)
473  simInfo[i].extendedClass =
475  else
476  simInfo[i].extendedClass =
478  } else if (simInfo[i].motherStatus != -1) { // primary light particle
479  int id = std::abs(simInfo[i].motherPdgId);
480  if (id != /*pi+*/ 211 && id != /*K+*/ 321 && id != 130 /*K0L*/)
481  // other light particle, possibly short-lived
482  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromOtherLight
484  else if (simInfo[i].vertex.Rho() < decayRho_ && std::abs(simInfo[i].vertex.Z()) < decayAbsZ_)
485  // decay a la ppMuX (primary pi/K within a cylinder)
486  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromPiKppMuX
488  else
489  // late decay that wouldn't be in ppMuX
490  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromPiKNotppMuX
492  } else
493  // decay of non-primary particle, would not be in ppMuX
494  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromNonPrimaryParticle
496 
497  if (linkToGenParticles_ && std::abs(simInfo[i].extendedClass) >= 2) {
498  // Link to the genParticle if possible, but not decays in flight (in
499  // ppMuX they're in GEN block, but they have wrong parameters)
500  if (!tp->genParticles().empty() && std::abs(simInfo[i].extendedClass) >= 5) {
501  if (genParticles.id() != tp->genParticles().id()) {
502  throw cms::Exception("Configuration")
503  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id "
504  << genParticles.id() << ") and the references in the TrackingParticles (id " << tp->genParticles().id()
505  << ")\n";
506  }
507  muToPrimary[i] = tp->genParticles()[0].key();
508  } else {
509  // Don't put the same trackingParticle twice!
510  int &indexPlus1 = tpToSecondaries[tp]; // will create a 0 if the tp is
511  // not in the list already
512  if (indexPlus1 == 0)
513  indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
514  muToSecondary[i] = indexPlus1 - 1;
515  }
516  }
517  LogTrace("MuonSimClassifier") << "\t Extended classification code = " << simInfo[i].extendedClass;
518  } else { // if (tp.isNonnull())
519  simInfo[i].primaryClass = reco::MuonSimType::NotMatched;
520  simInfo[i].extendedClass = reco::ExtendedMuonSimType::ExtNotMatched;
521  }
522  } // end loop on reco muons
523 
524  writeValueMap(iEvent, muons, simInfo, "");
525 
526  if (linkToGenParticles_) {
527  edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
528  edm::RefProd<reco::GenParticleCollection> priRP(genParticles);
530  std::unique_ptr<edm::Association<reco::GenParticleCollection>> outPri(
532  std::unique_ptr<edm::Association<reco::GenParticleCollection>> outSec(
534  edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
535  fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
536  fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
537  fillPri.fill();
538  fillSec.fill();
539  iEvent.put(std::move(outPri), "toPrimaries");
540  iEvent.put(std::move(outSec), "toSecondaries");
541  }
542 }
543 
544 template <typename T>
547  const std::vector<T> &values,
548  const std::string &label) const {
549  using namespace edm;
550  using namespace std;
551  unique_ptr<ValueMap<T>> valMap(new ValueMap<T>());
552  typename edm::ValueMap<T>::Filler filler(*valMap);
553  filler.insert(handle, values.begin(), values.end());
554  filler.fill();
555  iEvent.put(std::move(valMap), label);
556 }
557 
559  int flav = std::abs(pdgId);
560  // for quarks, leptons and bosons except gluons, take their pdgId
561  // muons and taus have themselves as flavour
562  if (flav <= 37 && flav != 21)
563  return flav;
564  // look for barions
565  int bflav = ((flav / 1000) % 10);
566  if (bflav != 0)
567  return bflav;
568  // look for mesons
569  int mflav = ((flav / 100) % 10);
570  if (mflav != 0)
571  return mflav;
572  return 0;
573 }
574 
575 // push secondary in collection.
576 // if it has a primary mother link to it.
579  const TrackingParticleRef &simMom,
581  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
582  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
583  if (genParticles.id() != simMom->genParticles().id()) {
584  throw cms::Exception("Configuration")
585  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id " << genParticles.id()
586  << ") and the references in the TrackingParticles (id " << simMom->genParticles().id() << ")\n";
587  }
588  out.back().addMother(simMom->genParticles()[0]);
589  }
590  return out.size() - 1;
591 }
592 
593 // define this as a plug-in
const LorentzVector & p4() const
Four-momentum Lorentz vector. Note this is taken from the first SimTrack only.
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
Definition: MuonTrackType.h:37
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
std::vector< TrackingParticle > TrackingParticleCollection
ProductID id() const
Definition: HandleBase.cc:15
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
TrackingParticleRef getTpMother(TrackingParticleRef tp)
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
void writeValueMap(edm::Event &iEvent, const edm::Handle< edm::View< reco::Muon >> &handle, const std::vector< T > &values, const std::string &label) const
Write a ValueMap<int> in the event.
void produce(edm::Event &, const edm::EventSetup &) override
int pdgId() const
PDG ID.
reco::MuonTrackType trackType_
Track to use.
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
int flavour(int pdgId) const
Returns the flavour given a pdg id code.
int convertAndPush(const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
key_type key() const
Accessor for product key.
Definition: Ref.h:263
value_type at(size_type idx) const
int status() const
Status word.
ProductID id() const
Accessor for product ID.
Definition: Ref.h:257
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
Definition: MuonTrackType.h:38
char const * label
float charge() const
Electric charge. Note this is taken from the first SimTrack only.
edm::InputTag genParticles_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Definition: Muon.py:1
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &muons, MuonTrackType type, const edm::RefVector< TrackingParticleCollection > &tpColl) const
MuonSimClassifier(const edm::ParameterSet &)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
#define LogTrace(id)
T const * product() const
Definition: Handle.h:74
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
void dumpFormatedInfo(const reco::MuonSimInfo &simInfo)
LorentzVector p4
Definition: MuonSimInfo.h:95
edm::InputTag associatorLabel_
The Associations.
Point vertex() const
Parent vertex position.
fixed size matrix
HLT enums.
double decayRho_
Cylinder to use to decide if a decay is early or late.
void push_back(const RefToBase< T > &)
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Definition: RefVector.h:69
Monte Carlo truth information used for tracking validation.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
MuonTrackType
Definition: MuonTrackType.h:28
bool linkToGenParticles_
Create a link to the generator level particles.
edm::Ref< TrackingParticleCollection > TrackingParticleRef
def move(src, dest)
Definition: eostools.py:511
~MuonSimClassifier() override