CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
MuonSimClassifier Class Reference
Inheritance diagram for MuonSimClassifier:
edm::stream::EDProducer<>

Public Member Functions

 MuonSimClassifier (const edm::ParameterSet &)
 
 ~MuonSimClassifier () override
 
- Public Member Functions inherited from edm::stream::EDProducer<>
 EDProducer ()=default
 
 EDProducer (const EDProducer &)=delete
 
bool hasAbilityToProduceInBeginLumis () const final
 
bool hasAbilityToProduceInBeginProcessBlocks () const final
 
bool hasAbilityToProduceInBeginRuns () const final
 
bool hasAbilityToProduceInEndLumis () const final
 
bool hasAbilityToProduceInEndProcessBlocks () const final
 
bool hasAbilityToProduceInEndRuns () const final
 
const EDProduceroperator= (const EDProducer &)=delete
 

Private Member Functions

int convertAndPush (const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
 
int flavour (int pdgId) const
 Returns the flavour given a pdg id code. More...
 
TrackingParticleRef getTpMother (TrackingParticleRef tp)
 
void produce (edm::Event &, const edm::EventSetup &) override
 
template<typename T >
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. More...
 

Private Attributes

edm::InputTag associatorLabel_
 The Associations. More...
 
double decayAbsZ_
 
double decayRho_
 Cylinder to use to decide if a decay is early or late. More...
 
edm::InputTag genParticles_
 
edm::EDGetTokenT< reco::GenParticleCollectiongenParticlesToken_
 
bool linkToGenParticles_
 Create a link to the generator level particles. More...
 
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociatormuAssocToken_
 
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
 The RECO objects. More...
 
edm::EDGetTokenT< TrackingParticleCollectiontrackingParticlesToken_
 The TrackingParticle objects. More...
 
reco::MuonTrackType trackType_
 Track to use. More...
 

Additional Inherited Members

- Public Types inherited from edm::stream::EDProducer<>
using CacheTypes = CacheContexts< T... >
 
using GlobalCache = typename CacheTypes::GlobalCache
 
using HasAbility = AbilityChecker< T... >
 
using InputProcessBlockCache = typename CacheTypes::InputProcessBlockCache
 
using LuminosityBlockCache = typename CacheTypes::LuminosityBlockCache
 
using LuminosityBlockContext = LuminosityBlockContextT< LuminosityBlockCache, RunCache, GlobalCache >
 
using LuminosityBlockSummaryCache = typename CacheTypes::LuminosityBlockSummaryCache
 
using RunCache = typename CacheTypes::RunCache
 
using RunContext = RunContextT< RunCache, GlobalCache >
 
using RunSummaryCache = typename CacheTypes::RunSummaryCache
 

Detailed Description

Definition at line 69 of file MuonSimClassifier.cc.

Constructor & Destructor Documentation

◆ MuonSimClassifier()

MuonSimClassifier::MuonSimClassifier ( const edm::ParameterSet iConfig)
explicit

Definition at line 124 of file MuonSimClassifier.cc.

References Exception, genParticles_, genParticlesToken_, edm::ParameterSet::getParameter(), reco::GlbOrTrk, reco::GlobalTk, reco::InnerTk, linkToGenParticles_, reco::OuterTk, reco::Segments, AlCaHLTBitMon_QueryRunRegistry::string, PbPb_ZMuSkimMuonDPG_cff::trackType, and trackType_.

125  : muonsToken_(consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("muons"))),
127  consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
129  consumes<reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::InputTag>("associatorLabel"))),
130  decayRho_(iConfig.getParameter<double>("decayRho")),
131  decayAbsZ_(iConfig.getParameter<double>("decayAbsZ")),
132  linkToGenParticles_(iConfig.getParameter<bool>("linkToGenParticles")),
134 
135 {
136  std::string trackType = iConfig.getParameter<std::string>("trackType");
137  if (trackType == "inner")
139  else if (trackType == "outer")
141  else if (trackType == "global")
143  else if (trackType == "segments")
145  else if (trackType == "glb_or_trk")
147  else
148  throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
149  if (linkToGenParticles_) {
150  genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
151  }
152 
153  produces<edm::ValueMap<reco::MuonSimInfo>>();
154  if (linkToGenParticles_) {
155  produces<reco::GenParticleCollection>("secondaries");
156  produces<edm::Association<reco::GenParticleCollection>>("toPrimaries");
157  produces<edm::Association<reco::GenParticleCollection>>("toSecondaries");
158  }
159 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
reco::MuonTrackType trackType_
Track to use.
edm::InputTag genParticles_
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
double decayRho_
Cylinder to use to decide if a decay is early or late.
bool linkToGenParticles_
Create a link to the generator level particles.

◆ ~MuonSimClassifier()

MuonSimClassifier::~MuonSimClassifier ( )
override

Definition at line 161 of file MuonSimClassifier.cc.

161 {}

Member Function Documentation

◆ convertAndPush()

int MuonSimClassifier::convertAndPush ( const TrackingParticle tp,
reco::GenParticleCollection out,
const TrackingParticleRef momRef,
const edm::Handle< reco::GenParticleCollection > &  genParticles 
) const
private

Convert TrackingParticle into GenParticle, save into output collection, if mother is primary set reference to it, return index in output collection

Definition at line 576 of file MuonSimClassifier.cc.

References Exception, AJJGenJetFilter_cfi::genParticles, genParticles_, edm::Ref< C, T, F >::id(), edm::Ref< C, T, F >::isNonnull(), MillePedeFileConverter_cfg::out, and cmsswSequenceInfo::tp.

Referenced by produce().

579  {
580  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
581  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
582  if (genParticles.id() != simMom->genParticles().id()) {
583  throw cms::Exception("Configuration")
584  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id " << genParticles.id()
585  << ") and the references in the TrackingParticles (id " << simMom->genParticles().id() << ")\n";
586  }
587  out.back().addMother(simMom->genParticles()[0]);
588  }
589  return out.size() - 1;
590 }
edm::InputTag genParticles_

◆ flavour()

int MuonSimClassifier::flavour ( int  pdgId) const
private

Returns the flavour given a pdg id code.

Definition at line 557 of file MuonSimClassifier.cc.

References funct::abs(), and EgammaValidation_cff::pdgId.

Referenced by produce().

557  {
558  int flav = std::abs(pdgId);
559  // for quarks, leptons and bosons except gluons, take their pdgId
560  // muons and taus have themselves as flavour
561  if (flav <= 37 && flav != 21)
562  return flav;
563  // look for barions
564  int bflav = ((flav / 1000) % 10);
565  if (bflav != 0)
566  return bflav;
567  // look for mesons
568  int mflav = ((flav / 100) % 10);
569  if (mflav != 0)
570  return mflav;
571  return 0;
572 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22

◆ getTpMother()

TrackingParticleRef MuonSimClassifier::getTpMother ( TrackingParticleRef  tp)
inlineprivate

Definition at line 107 of file MuonSimClassifier.cc.

References cmsswSequenceInfo::tp.

Referenced by produce().

107  {
108  if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
109  return tp->parentVertex()->sourceTracks()[0];
110  } else {
111  return TrackingParticleRef();
112  }
113  }
edm::Ref< TrackingParticleCollection > TrackingParticleRef

◆ produce()

void MuonSimClassifier::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
overrideprivate

Definition at line 174 of file MuonSimClassifier.cc.

References funct::abs(), allMuons_cfi::allMuons, reco::MuonToTrackingParticleAssociator::associateMuons(), convertAndPush(), decayAbsZ_, decayRho_, dumpFormatedInfo(), Exception, reco::ExtGhostElectron, reco::ExtGhostPunchthrough, reco::ExtMatchedElectron, reco::ExtMatchedPunchthrough, reco::ExtNotMatched, edm::helper::Filler< Map >::fill(), flavour(), EgammaValidation_cff::genp, AJJGenJetFilter_cfi::genParticles, genParticles_, genParticlesToken_, getTpMother(), reco::GhostElectron, reco::GhostMuonFromB, reco::GhostMuonFromBtoC, reco::GhostMuonFromC, reco::GhostMuonFromGaugeOrHiggsBoson, reco::GhostMuonFromHeavyFlavour, reco::GhostMuonFromLightFlavour, reco::GhostMuonFromNonPrimaryParticle, reco::GhostMuonFromOtherLight, reco::GhostMuonFromPiKNotppMuX, reco::GhostMuonFromPiKppMuX, reco::GhostMuonFromTau, reco::GhostPrimaryMuon, reco::GhostPunchthrough, reco::GlobalTk, mps_fire::i, iEvent, edm::helper::Filler< Map >::insert(), edm::Ref< C, T, F >::isNonnull(), linkToGenParticles_, LogTrace, match(), reco::MatchedElectron, reco::MatchedMuonFromB, reco::MatchedMuonFromBtoC, reco::MatchedMuonFromC, reco::MatchedMuonFromGaugeOrHiggsBoson, reco::MatchedMuonFromHeavyFlavour, reco::MatchedMuonFromLightFlavour, reco::MatchedMuonFromNonPrimaryParticle, reco::MatchedMuonFromOtherLight, reco::MatchedMuonFromPiKNotppMuX, reco::MatchedMuonFromPiKppMuX, reco::MatchedMuonFromTau, reco::MatchedPrimaryMuon, reco::MatchedPunchthrough, eostools::move(), muAssocToken_, DiMuonV_cfg::muons, muonsToken_, dqmiodumpmetadata::n, reco::NotMatched, reco::OuterTk, edm::Handle< T >::product(), edm::RefVector< C, T, F >::push_back(), cmsswSequenceInfo::tp, muonClassificationByHits_cfi::trackingParticles, trackingParticlesToken_, trackType_, bphysicsOniaDQM_cfi::vertex, and writeValueMap().

174  {
176  iEvent.getByToken(muonsToken_, muons);
177 
180 
182  if (linkToGenParticles_) {
184  }
185 
187  iEvent.getByToken(muAssocToken_, associatorBase);
188  const reco::MuonToTrackingParticleAssociator *assoByHits = associatorBase.product();
189 
190  reco::MuonToSimCollection recSimColl;
191  reco::SimToMuonCollection simRecColl;
192  LogTrace("MuonSimClassifier") << "\n "
193  "***************************************************************** ";
194  LogTrace("MuonSimClassifier") << " RECO MUON association, type: " << trackType_;
195  LogTrace("MuonSimClassifier") << " ******************************************"
196  "*********************** \n";
197 
199  for (size_t i = 0, n = muons->size(); i < n; ++i) {
200  allMuons.push_back(muons->refAt(i));
201  }
202 
204  for (size_t i = 0, n = trackingParticles->size(); i < n; ++i) {
206  }
207 
208  assoByHits->associateMuons(recSimColl, simRecColl, allMuons, trackType_, allTPs);
209 
210  // for global muons without hits on muon detectors, look at the linked
211  // standalone muon
212  reco::MuonToSimCollection updSTA_recSimColl;
213  reco::SimToMuonCollection updSTA_simRecColl;
214  if (trackType_ == reco::GlobalTk) {
215  LogTrace("MuonSimClassifier") << "\n "
216  "***************************************************************** ";
217  LogTrace("MuonSimClassifier") << " STANDALONE (UpdAtVtx) MUON association ";
218  LogTrace("MuonSimClassifier") << " ****************************************"
219  "************************* \n";
220  assoByHits->associateMuons(updSTA_recSimColl, updSTA_simRecColl, allMuons, reco::OuterTk, allTPs);
221  }
222 
223  typedef reco::MuonToSimCollection::const_iterator r2s_it;
224  typedef reco::SimToMuonCollection::const_iterator s2r_it;
225 
226  size_t nmu = muons->size();
227  LogTrace("MuonSimClassifier") << "\n There are " << nmu << " reco::Muons.";
228 
229  std::vector<reco::MuonSimInfo> simInfo;
230 
231  std::unique_ptr<reco::GenParticleCollection> secondaries; // output collection of secondary muons
232  std::map<TrackingParticleRef, int> tpToSecondaries; // map from tp to (index+1) in output collection
233  std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu,
234  -1); // map from input into (index) in output, -1 for null
236  secondaries = std::make_unique<reco::GenParticleCollection>();
237 
238  // loop on reco muons
239  for (size_t i = 0; i < nmu; ++i) {
240  simInfo.push_back(reco::MuonSimInfo());
241  LogTrace("MuonSimClassifier") << "\n reco::Muon # " << i;
242 
244  edm::RefToBase<reco::Muon> muMatchBack;
245  r2s_it match = recSimColl.find(allMuons.at(i));
246  s2r_it matchback;
247  if (match != recSimColl.end()) {
248  // match->second is vector, front is first element, first is the ref
249  // (second would be the quality)
250  tp = match->second.front().first;
251  simInfo[i].tpId = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
252  simInfo[i].tpAssoQuality = match->second.front().second;
253  s2r_it matchback = simRecColl.find(tp);
254  if (matchback != simRecColl.end()) {
255  muMatchBack = matchback->second.front().first;
256  } else {
257  LogTrace("MuonSimClassifier") << "\n***WARNING: This I do NOT understand: why no match back? "
258  "*** \n";
259  }
260  } else {
261  if ((trackType_ == reco::GlobalTk) && allMuons.at(i)->isGlobalMuon()) {
262  // perform a second attempt, matching with the standalone muon
263  r2s_it matchSta = updSTA_recSimColl.find(allMuons.at(i));
264  if (matchSta != updSTA_recSimColl.end()) {
265  tp = matchSta->second.front().first;
266  simInfo[i].tpId = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs
267  // should not appear here at all
268  simInfo[i].tpAssoQuality = matchSta->second.front().second;
269  s2r_it matchback = updSTA_simRecColl.find(tp);
270  if (matchback != updSTA_simRecColl.end()) {
271  muMatchBack = matchback->second.front().first;
272  } else {
273  LogTrace("MuonSimClassifier") << "\n***WARNING: This I do NOT understand: why no match back "
274  "in updSTA? *** \n";
275  }
276  }
277  } else {
278  LogTrace("MuonSimClassifier") << "\t No matching TrackingParticle is found ";
279  }
280  }
281 
282  if (tp.isNonnull()) {
283  bool isGhost = muMatchBack != allMuons.at(i);
284  if (isGhost)
285  LogTrace("MuonSimClassifier") << "\t *** This seems a Duplicate muon ! "
286  "classif[i] will be < 0 ***";
287 
288  // identify signal and pileup TP
289  simInfo[i].tpBX = tp->eventId().bunchCrossing();
290  simInfo[i].tpEvent = tp->eventId().event();
291 
292  simInfo[i].pdgId = tp->pdgId();
293  simInfo[i].vertex = tp->vertex();
294 
295  // added info on GEANT process producing the TrackingParticle
296  const std::vector<SimVertex> &g4Vs = tp->parentVertex()->g4Vertices();
297  simInfo[i].g4processType = g4Vs[0].processType();
298 
299  simInfo[i].charge = tp->charge();
300  simInfo[i].p4 = tp->p4();
301 
302  // Try to extract mother and grand mother of this muon.
303  // Unfortunately, SIM and GEN histories require diffent code :-(
304  if (!tp->genParticles().empty()) { // Muon is in GEN
305  reco::GenParticleRef genp = tp->genParticles()[0];
306  reco::GenParticleRef genMom = genp->numberOfMothers() > 0 ? genp->motherRef() : reco::GenParticleRef();
307  reco::GenParticleRef mMom = genMom;
308 
309  if (genMom.isNonnull()) {
310  if (genMom->pdgId() != tp->pdgId()) {
311  simInfo[i].motherPdgId = genMom->pdgId();
312  simInfo[i].motherStatus = genMom->status();
313  simInfo[i].motherVertex = genMom->vertex();
314  } else {
315  // if mother has the same identity look backwards for the real
316  // mother (it may happen in radiative decays)
317  int jm = 0;
318  while (mMom->pdgId() == tp->pdgId()) {
319  jm++;
320  if (mMom->numberOfMothers() > 0) {
321  mMom = mMom->motherRef();
322  } else {
323  LogTrace("MuonSimClassifier") << "\t No Mother is found ";
324  break;
325  }
326 
327  LogTrace("MuonSimClassifier") << "\t\t backtracking mother " << jm << ", pdgId = " << mMom->pdgId()
328  << ", status= " << mMom->status();
329  }
330  genMom = mMom; // redefine genMom
331  simInfo[i].motherPdgId = genMom->pdgId();
332  simInfo[i].motherStatus = genMom->status();
333  simInfo[i].motherVertex = genMom->vertex();
334  }
335  dumpFormatedInfo(simInfo[i]);
336  LogTrace("MuonSimClassifier") << "\t has GEN mother pdgId = " << simInfo[i].motherPdgId
337  << " (status = " << simInfo[i].motherStatus << ")";
338 
339  reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
340 
341  if (genGMom.isNonnull()) {
342  simInfo[i].grandMotherPdgId = genGMom->pdgId();
343  LogTrace("MuonSimClassifier")
344  << "\t\t mother prod. vertex rho = " << simInfo[i].motherVertex.Rho()
345  << ", z = " << simInfo[i].motherVertex.Z() << ", grand-mom pdgId = " << simInfo[i].grandMotherPdgId;
346  }
347  // in this case, we might want to know the heaviest mom flavour
348  for (reco::GenParticleRef nMom = genMom;
349  nMom.isNonnull() && std::abs(nMom->pdgId()) >= 100; // stop when we're no longer
350  // looking at hadrons or mesons
351  nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
352  int flav = flavour(nMom->pdgId());
353  if (simInfo[i].heaviestMotherFlavour < flav)
354  simInfo[i].heaviestMotherFlavour = flav;
355  LogTrace("MuonSimClassifier")
356  << "\t\t backtracking flavour: mom pdgId = " << nMom->pdgId() << ", flavour = " << flav
357  << ", heaviest so far = " << simInfo[i].heaviestMotherFlavour;
358  }
359  } else { // mother is null ??
360  dumpFormatedInfo(simInfo[i]);
361  LogTrace("MuonSimClassifier") << "\t has NO mother!";
362  }
363  } else { // Muon is in SIM Only
365  if (simMom.isNonnull()) {
366  simInfo[i].motherPdgId = simMom->pdgId();
367  simInfo[i].motherVertex = simMom->vertex();
368  dumpFormatedInfo(simInfo[i]);
369  LogTrace("MuonSimClassifier") << "\t has SIM mother pdgId = " << simInfo[i].motherPdgId
370  << " produced at rho = " << simMom->vertex().Rho()
371  << ", z = " << simMom->vertex().Z();
372 
373  if (!simMom->genParticles().empty()) {
374  simInfo[i].motherStatus = simMom->genParticles()[0]->status();
375  reco::GenParticleRef genGMom =
376  (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
378  if (genGMom.isNonnull())
379  simInfo[i].grandMotherPdgId = genGMom->pdgId();
380  LogTrace("MuonSimClassifier") << "\t\t SIM mother is in GEN (status " << simInfo[i].motherStatus
381  << "), grand-mom id = " << simInfo[i].grandMotherPdgId;
382  } else {
383  simInfo[i].motherStatus = -1;
384  TrackingParticleRef simGMom = getTpMother(simMom);
385  if (simGMom.isNonnull())
386  simInfo[i].grandMotherPdgId = simGMom->pdgId();
387  LogTrace("MuonSimClassifier")
388  << "\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[i].grandMotherPdgId;
389  }
390  } else {
391  dumpFormatedInfo(simInfo[i]);
392  LogTrace("MuonSimClassifier") << "\t has NO mother!";
393  }
394  }
395  simInfo[i].motherFlavour = flavour(simInfo[i].motherPdgId);
396  simInfo[i].grandMotherFlavour = flavour(simInfo[i].grandMotherPdgId);
397 
398  // Check first IF this is a muon at all
399  if (std::abs(tp->pdgId()) != 13) {
400  if (std::abs(tp->pdgId()) == 11) {
401  simInfo[i].primaryClass = isGhost ? reco::MuonSimType::GhostElectron : reco::MuonSimType::MatchedElectron;
402  simInfo[i].extendedClass =
404  LogTrace("MuonSimClassifier") << "\t This is electron/positron. classif[i] = " << simInfo[i].primaryClass;
405  } else {
406  simInfo[i].primaryClass =
408  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::ExtGhostPunchthrough
410  LogTrace("MuonSimClassifier") << "\t This is not a muon. Sorry. classif[i] = " << simInfo[i].primaryClass;
411  }
412  continue;
413  }
414 
415  // Is this SIM muon also a GEN muon, with a mother?
416  if (!tp->genParticles().empty() && (simInfo[i].motherPdgId != 0)) {
417  if (std::abs(simInfo[i].motherPdgId) < 100 && (std::abs(simInfo[i].motherPdgId) != 15)) {
418  simInfo[i].primaryClass =
420  simInfo[i].flavour = 13;
421  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromGaugeOrHiggsBoson
423  LogTrace("MuonSimClassifier") << "\t This seems PRIMARY MUON ! classif[i] = " << simInfo[i].primaryClass;
424  } else if (simInfo[i].motherFlavour == 4 || simInfo[i].motherFlavour == 5 || simInfo[i].motherFlavour == 15) {
425  simInfo[i].primaryClass =
427  simInfo[i].flavour = simInfo[i].motherFlavour;
428  if (simInfo[i].motherFlavour == 15)
429  simInfo[i].extendedClass =
431  else if (simInfo[i].motherFlavour == 5)
432  simInfo[i].extendedClass =
434  else if (simInfo[i].heaviestMotherFlavour == 5)
435  simInfo[i].extendedClass =
437  else
438  simInfo[i].extendedClass =
440  LogTrace("MuonSimClassifier") << "\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
441  } else {
442  simInfo[i].primaryClass =
444  simInfo[i].flavour = simInfo[i].motherFlavour;
445  LogTrace("MuonSimClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
446  }
447  } else {
448  simInfo[i].primaryClass =
450  simInfo[i].flavour = simInfo[i].motherFlavour;
451  LogTrace("MuonSimClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
452  }
453 
454  // extended classification
455  // don't we override previous decisions?
456  if (simInfo[i].motherPdgId == 0)
457  // if it has no mom, it's not a primary particle so it won't be in ppMuX
458  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromNonPrimaryParticle
460  else if (std::abs(simInfo[i].motherPdgId) < 100) {
461  if (simInfo[i].motherFlavour == 15)
462  simInfo[i].extendedClass =
464  else
465  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromGaugeOrHiggsBoson
467  } else if (simInfo[i].motherFlavour == 5)
468  simInfo[i].extendedClass =
470  else if (simInfo[i].motherFlavour == 4) {
471  if (simInfo[i].heaviestMotherFlavour == 5)
472  simInfo[i].extendedClass =
474  else
475  simInfo[i].extendedClass =
477  } else if (simInfo[i].motherStatus != -1) { // primary light particle
478  int id = std::abs(simInfo[i].motherPdgId);
479  if (id != /*pi+*/ 211 && id != /*K+*/ 321 && id != 130 /*K0L*/)
480  // other light particle, possibly short-lived
481  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromOtherLight
483  else if (simInfo[i].vertex.Rho() < decayRho_ && std::abs(simInfo[i].vertex.Z()) < decayAbsZ_)
484  // decay a la ppMuX (primary pi/K within a cylinder)
485  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromPiKppMuX
487  else
488  // late decay that wouldn't be in ppMuX
489  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromPiKNotppMuX
491  } else
492  // decay of non-primary particle, would not be in ppMuX
493  simInfo[i].extendedClass = isGhost ? reco::ExtendedMuonSimType::GhostMuonFromNonPrimaryParticle
495 
496  if (linkToGenParticles_ && std::abs(simInfo[i].extendedClass) >= 2) {
497  // Link to the genParticle if possible, but not decays in flight (in
498  // ppMuX they're in GEN block, but they have wrong parameters)
499  if (!tp->genParticles().empty() && std::abs(simInfo[i].extendedClass) >= 5) {
500  if (genParticles.id() != tp->genParticles().id()) {
501  throw cms::Exception("Configuration")
502  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id "
503  << genParticles.id() << ") and the references in the TrackingParticles (id " << tp->genParticles().id()
504  << ")\n";
505  }
506  muToPrimary[i] = tp->genParticles()[0].key();
507  } else {
508  // Don't put the same trackingParticle twice!
509  int &indexPlus1 = tpToSecondaries[tp]; // will create a 0 if the tp is
510  // not in the list already
511  if (indexPlus1 == 0)
512  indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
513  muToSecondary[i] = indexPlus1 - 1;
514  }
515  }
516  LogTrace("MuonSimClassifier") << "\t Extended classification code = " << simInfo[i].extendedClass;
517  } else { // if (tp.isNonnull())
518  simInfo[i].primaryClass = reco::MuonSimType::NotMatched;
519  simInfo[i].extendedClass = reco::ExtendedMuonSimType::ExtNotMatched;
520  }
521  } // end loop on reco muons
522 
523  writeValueMap(iEvent, muons, simInfo, "");
524 
525  if (linkToGenParticles_) {
526  edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
529  std::unique_ptr<edm::Association<reco::GenParticleCollection>> outPri(
531  std::unique_ptr<edm::Association<reco::GenParticleCollection>> outSec(
533  edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
534  fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
535  fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
536  fillPri.fill();
537  fillSec.fill();
538  iEvent.put(std::move(outPri), "toPrimaries");
539  iEvent.put(std::move(outSec), "toSecondaries");
540  }
541 }
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
Definition: MuonTrackType.h:37
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &muons, MuonTrackType type, const edm::RefVector< TrackingParticleCollection > &tpColl) const
genp
produce generated paricles in acceptance #
TrackingParticleRef getTpMother(TrackingParticleRef tp)
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
reco::MuonTrackType trackType_
Track to use.
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
T const * product() const
Definition: Handle.h:70
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:212
#define LogTrace(id)
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
Definition: MuonTrackType.h:38
edm::InputTag genParticles_
int iEvent
Definition: GenABIO.cc:224
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
void dumpFormatedInfo(const reco::MuonSimInfo &simInfo)
double decayRho_
Cylinder to use to decide if a decay is early or late.
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Definition: RefVector.h:67
int convertAndPush(const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
bool linkToGenParticles_
Create a link to the generator level particles.
edm::Ref< TrackingParticleCollection > TrackingParticleRef
def move(src, dest)
Definition: eostools.py:511
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.
int flavour(int pdgId) const
Returns the flavour given a pdg id code.

◆ writeValueMap()

template<typename T >
void MuonSimClassifier::writeValueMap ( edm::Event iEvent,
const edm::Handle< edm::View< reco::Muon >> &  handle,
const std::vector< T > &  values,
const std::string &  label 
) const
private

Write a ValueMap<int> in the event.

Definition at line 544 of file MuonSimClassifier.cc.

References trigObjTnPSource_cfi::filler, patZpeak::handle, iEvent, label, eostools::move(), and contentValuesCheck::values.

Referenced by produce().

547  {
548  using namespace edm;
549  using namespace std;
550  unique_ptr<ValueMap<T>> valMap(new ValueMap<T>());
551  typename edm::ValueMap<T>::Filler filler(*valMap);
552  filler.insert(handle, values.begin(), values.end());
553  filler.fill();
554  iEvent.put(std::move(valMap), label);
555 }
char const * label
int iEvent
Definition: GenABIO.cc:224
HLT enums.
def move(src, dest)
Definition: eostools.py:511

Member Data Documentation

◆ associatorLabel_

edm::InputTag MuonSimClassifier::associatorLabel_
private

The Associations.

Definition at line 86 of file MuonSimClassifier.cc.

◆ decayAbsZ_

double MuonSimClassifier::decayAbsZ_
private

Definition at line 90 of file MuonSimClassifier.cc.

Referenced by produce().

◆ decayRho_

double MuonSimClassifier::decayRho_
private

Cylinder to use to decide if a decay is early or late.

Definition at line 90 of file MuonSimClassifier.cc.

Referenced by produce().

◆ genParticles_

edm::InputTag MuonSimClassifier::genParticles_
private

Definition at line 94 of file MuonSimClassifier.cc.

Referenced by convertAndPush(), MuonSimClassifier(), and produce().

◆ genParticlesToken_

edm::EDGetTokenT<reco::GenParticleCollection> MuonSimClassifier::genParticlesToken_
private

Definition at line 95 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().

◆ linkToGenParticles_

bool MuonSimClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 93 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().

◆ muAssocToken_

edm::EDGetTokenT<reco::MuonToTrackingParticleAssociator> MuonSimClassifier::muAssocToken_
private

Definition at line 87 of file MuonSimClassifier.cc.

Referenced by produce().

◆ muonsToken_

edm::EDGetTokenT<edm::View<reco::Muon> > MuonSimClassifier::muonsToken_
private

The RECO objects.

Definition at line 77 of file MuonSimClassifier.cc.

Referenced by produce().

◆ trackingParticlesToken_

edm::EDGetTokenT<TrackingParticleCollection> MuonSimClassifier::trackingParticlesToken_
private

The TrackingParticle objects.

Definition at line 83 of file MuonSimClassifier.cc.

Referenced by produce().

◆ trackType_

reco::MuonTrackType MuonSimClassifier::trackType_
private

Track to use.

Definition at line 80 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().