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