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
 
bool hasAbilityToProduceInLumis () const final
 
bool hasAbilityToProduceInRuns () const final
 

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<>
typedef CacheContexts< T... > CacheTypes
 
typedef CacheTypes::GlobalCache GlobalCache
 
typedef AbilityChecker< T... > HasAbility
 
typedef CacheTypes::LuminosityBlockCache LuminosityBlockCache
 
typedef LuminosityBlockContextT< LuminosityBlockCache, RunCache, GlobalCacheLuminosityBlockContext
 
typedef CacheTypes::LuminosityBlockSummaryCache LuminosityBlockSummaryCache
 
typedef CacheTypes::RunCache RunCache
 
typedef RunContextT< RunCache, GlobalCacheRunContext
 
typedef CacheTypes::RunSummaryCache RunSummaryCache
 

Detailed Description

Definition at line 67 of file MuonSimClassifier.cc.

Constructor & Destructor Documentation

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

Definition at line 123 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, tkIsoDeposits_cff::trackType, and trackType_.

123  :
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")),
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 }
T getParameter(std::string const &) const
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 ( )
override

Definition at line 152 of file MuonSimClassifier.cc.

153 {
154 }

Member Function Documentation

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 565 of file MuonSimClassifier.cc.

References TrackingParticle::charge(), DEFINE_FWK_MODULE, Exception, genParticles_, edm::HandleBase::id(), edm::Ref< C, T, F >::id(), edm::Ref< C, T, F >::isNonnull(), TrackingParticle::p4(), TrackingParticle::pdgId(), TrackingParticle::status(), and TrackingParticle::vertex().

Referenced by getTpMother(), and produce().

568  {
569  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
570  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
571  if (genParticles.id() != simMom->genParticles().id()) {
572  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";
573  }
574  out.back().addMother(simMom->genParticles()[0]);
575  }
576  return out.size()-1;
577 }
const LorentzVector & p4() const
Four-momentum Lorentz vector. Note this is taken from the first SimTrack only.
ProductID id() const
Definition: HandleBase.cc:15
int pdgId() const
PDG ID.
int status() const
Status word.
float charge() const
Electric charge. Note this is taken from the first SimTrack only.
edm::InputTag genParticles_
Point vertex() const
Parent vertex position.
ProductIndex id() const
Definition: ProductID.h:38
int MuonSimClassifier::flavour ( int  pdgId) const
private

Returns the flavour given a pdg id code.

Definition at line 549 of file MuonSimClassifier.cc.

References funct::abs().

Referenced by produce().

549  {
550  int flav = std::abs(pdgId);
551  // for quarks, leptons and bosons except gluons, take their pdgId
552  // muons and taus have themselves as flavour
553  if (flav <= 37 && flav != 21) return flav;
554  // look for barions
555  int bflav = ((flav / 1000) % 10);
556  if (bflav != 0) return bflav;
557  // look for mesons
558  int mflav = ((flav / 100) % 10);
559  if (mflav != 0) return mflav;
560  return 0;
561 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
TrackingParticleRef MuonSimClassifier::getTpMother ( TrackingParticleRef  tp)
inlineprivate

Definition at line 105 of file MuonSimClassifier.cc.

References convertAndPush(), GenHFHadronMatcher_cfi::genParticles, edm::Ref< C, T, F >::isNonnull(), and MillePedeFileConverter_cfg::out.

Referenced by produce().

105  {
106  if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
107  return tp->parentVertex()->sourceTracks()[0];
108  } else {
109  return TrackingParticleRef();
110  }
111  }
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
edm::Ref< TrackingParticleCollection > TrackingParticleRef
void MuonSimClassifier::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
overrideprivate

Definition at line 168 of file MuonSimClassifier.cc.

References funct::abs(), allMuons_cfi::allMuons, reco::MuonToTrackingParticleAssociator::associateMuons(), edm::RefToBaseVector< T >::at(), convertAndPush(), decayAbsZ_, decayRho_, dumpFormatedInfo(), Exception, reco::ExtGhostElectron, reco::ExtGhostPunchthrough, reco::ExtMatchedElectron, reco::ExtMatchedPunchthrough, reco::ExtNotMatched, edm::helper::Filler< Map >::fill(), flavour(), GenHFHadronMatcher_cfi::genParticles, genParticles_, genParticlesToken_, edm::Event::getByToken(), 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, edm::HandleBase::id(), edm::Ref< C, T, F >::id(), edm::helper::Filler< Map >::insert(), reco::Muon::isGlobalMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::key(), 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_, extraflags_cff::muons, muonsToken_, gen::n, reco::NotMatched, reco::OuterTk, edm::Handle< T >::product(), edm::RefToBaseVector< T >::push_back(), edm::RefVector< C, T, F >::push_back(), edm::Event::put(), trackingTruthProducer_cfi::trackingParticles, trackingParticlesToken_, trackType_, and writeValueMap().

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  LogTrace("MuonSimClassifier")
306  << "\t\t backtracking mother "<<jm<<", pdgId = "<<mMom->pdgId()<<", status= " <<mMom->status();
307  }
308  genMom = mMom; // redefine genMom
309  simInfo[i].motherPdgId = genMom->pdgId();
310  simInfo[i].motherStatus = genMom->status();
311  simInfo[i].motherVertex = genMom->vertex();
312  }
313  dumpFormatedInfo(simInfo[i]);
314  LogTrace("MuonSimClassifier") <<
315  "\t has GEN mother pdgId = " << simInfo[i].motherPdgId <<
316  " (status = " << simInfo[i].motherStatus << ")";
317 
318  reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
319 
320  if (genGMom.isNonnull()) {
321  simInfo[i].grandMotherPdgId = genGMom->pdgId();
322  LogTrace("MuonSimClassifier") <<
323  "\t\t mother prod. vertex rho = " << simInfo[i].motherVertex.Rho() << ", z = " << simInfo[i].motherVertex.Z() <<
324  ", grand-mom pdgId = " << simInfo[i].grandMotherPdgId;
325  }
326  // in this case, we might want to know the heaviest mom flavour
327  for (reco::GenParticleRef nMom = genMom;
328  nMom.isNonnull() && std::abs(nMom->pdgId()) >= 100; // stop when we're no longer looking at hadrons or mesons
329  nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
330  int flav = flavour(nMom->pdgId());
331  if (simInfo[i].heaviestMotherFlavour < flav) simInfo[i].heaviestMotherFlavour = flav;
332  LogTrace("MuonSimClassifier")
333  << "\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
334  << ", flavour = " << flav << ", heaviest so far = " << simInfo[i].heaviestMotherFlavour;
335  }
336  } else { // mother is null ??
337  dumpFormatedInfo(simInfo[i]);
338  LogTrace("MuonSimClassifier") <<"\t has NO mother!";
339  }
340  } else { // Muon is in SIM Only
341  TrackingParticleRef simMom = getTpMother(tp);
342  if (simMom.isNonnull()) {
343  simInfo[i].motherPdgId = simMom->pdgId();
344  simInfo[i].motherVertex = simMom->vertex();
345  dumpFormatedInfo(simInfo[i]);
346  LogTrace("MuonSimClassifier") <<
347  "\t has SIM mother pdgId = " << simInfo[i].motherPdgId <<
348  " produced at rho = " << simMom->vertex().Rho() << ", z = " << simMom->vertex().Z();
349 
350  if (!simMom->genParticles().empty()) {
351  simInfo[i].motherStatus = simMom->genParticles()[0]->status();
352  reco::GenParticleRef genGMom = (simMom->genParticles()[0]->numberOfMothers() > 0 ?
353  simMom->genParticles()[0]->motherRef() :
355  if (genGMom.isNonnull()) simInfo[i].grandMotherPdgId = genGMom->pdgId();
356  LogTrace("MuonSimClassifier") <<
357  "\t\t SIM mother is in GEN (status " << simInfo[i].motherStatus <<
358  "), grand-mom id = " << simInfo[i].grandMotherPdgId;
359  } else {
360  simInfo[i].motherStatus = -1;
361  TrackingParticleRef simGMom = getTpMother(simMom);
362  if (simGMom.isNonnull()) simInfo[i].grandMotherPdgId = simGMom->pdgId();
363  LogTrace("MuonSimClassifier") <<
364  "\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[i].grandMotherPdgId;
365  }
366  } else {
367  dumpFormatedInfo(simInfo[i]);
368  LogTrace("MuonSimClassifier") <<"\t has NO mother!";
369  }
370  }
371  simInfo[i].motherFlavour = flavour(simInfo[i].motherPdgId);
372  simInfo[i].grandMotherFlavour = flavour(simInfo[i].grandMotherPdgId);
373 
374  // Check first IF this is a muon at all
375  if (std::abs(tp->pdgId()) != 13) {
376  if (std::abs(tp->pdgId()) == 11) {
377  simInfo[i].primaryClass = isGhost ? reco::MuonSimType::GhostElectron : reco::MuonSimType::MatchedElectron;
379  LogTrace("MuonSimClassifier") <<"\t This is electron/positron. classif[i] = " << simInfo[i].primaryClass;
380  } else {
383  LogTrace("MuonSimClassifier") <<"\t This is not a muon. Sorry. classif[i] = " << simInfo[i].primaryClass;
384  }
385  continue;
386  }
387 
388  // Is this SIM muon also a GEN muon, with a mother?
389  if (!tp->genParticles().empty() && (simInfo[i].motherPdgId != 0)) {
390  if (std::abs(simInfo[i].motherPdgId) < 100 && (std::abs(simInfo[i].motherPdgId) != 15)) {
391  simInfo[i].primaryClass = isGhost ?
394  simInfo[i].flavour = 13;
395  simInfo[i].extendedClass = isGhost ?
398  LogTrace("MuonSimClassifier") <<"\t This seems PRIMARY MUON ! classif[i] = " << simInfo[i].primaryClass;
399  } else if (simInfo[i].motherFlavour == 4 || simInfo[i].motherFlavour == 5 || simInfo[i].motherFlavour == 15) {
400  simInfo[i].primaryClass = isGhost ?
403  simInfo[i].flavour = simInfo[i].motherFlavour;
404  if (simInfo[i].motherFlavour == 15)
405  simInfo[i].extendedClass = isGhost ?
408  else if (simInfo[i].motherFlavour == 5)
409  simInfo[i].extendedClass = isGhost ?
412  else if (simInfo[i].heaviestMotherFlavour == 5)
413  simInfo[i].extendedClass = isGhost ?
416  else
417  simInfo[i].extendedClass = isGhost ?
420  LogTrace("MuonSimClassifier") <<"\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
421  } else {
422  simInfo[i].primaryClass = isGhost ?
425  simInfo[i].flavour = simInfo[i].motherFlavour;
426  LogTrace("MuonSimClassifier") <<"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
427  }
428  } else {
429  simInfo[i].primaryClass = isGhost ?
432  simInfo[i].flavour = simInfo[i].motherFlavour;
433  LogTrace("MuonSimClassifier") <<"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[i].primaryClass;
434  }
435 
436  // extended classification
437  // don't we override previous decisions?
438  if (simInfo[i].motherPdgId == 0)
439  // if it has no mom, it's not a primary particle so it won't be in ppMuX
440  simInfo[i].extendedClass = isGhost ?
443  else if (std::abs(simInfo[i].motherPdgId) < 100) {
444  if (simInfo[i].motherFlavour == 15)
445  simInfo[i].extendedClass = isGhost ?
448  else
449  simInfo[i].extendedClass = isGhost ?
452  }
453  else if (simInfo[i].motherFlavour == 5)
454  simInfo[i].extendedClass = isGhost ?
457  else if (simInfo[i].motherFlavour == 4)
458  {
459  if (simInfo[i].heaviestMotherFlavour == 5)
460  simInfo[i].extendedClass = isGhost ?
463  else
464  simInfo[i].extendedClass = isGhost ?
467  }
468  else if (simInfo[i].motherStatus != -1) { // primary light particle
469  int id = std::abs(simInfo[i].motherPdgId);
470  if (id != /*pi+*/211 && id != /*K+*/321 && id != 130 /*K0L*/)
471  // other light particle, possibly short-lived
472  simInfo[i].extendedClass = isGhost ?
475  else if (simInfo[i].vertex.Rho() < decayRho_ && std::abs(simInfo[i].vertex.Z()) < decayAbsZ_)
476  // decay a la ppMuX (primary pi/K within a cylinder)
477  simInfo[i].extendedClass = isGhost ?
480  else
481  // late decay that wouldn't be in ppMuX
482  simInfo[i].extendedClass = isGhost ?
485  } else
486  // decay of non-primary particle, would not be in ppMuX
487  simInfo[i].extendedClass = isGhost ?
490 
491  if (linkToGenParticles_ && std::abs(simInfo[i].extendedClass) >= 2) {
492  // Link to the genParticle if possible, but not decays in flight (in ppMuX they're in GEN block, but they have wrong parameters)
493  if (!tp->genParticles().empty() && std::abs(simInfo[i].extendedClass) >= 5) {
494  if (genParticles.id() != tp->genParticles().id()) {
495  throw cms::Exception("Configuration") << "Product ID mismatch between the genParticle collection (" <<
496  genParticles_ << ", id " << genParticles.id() << ") and the references in the TrackingParticles (id " <<
497  tp->genParticles().id() << ")\n";
498  }
499  muToPrimary[i] = tp->genParticles()[0].key();
500  } else {
501  // Don't put the same trackingParticle twice!
502  int &indexPlus1 = tpToSecondaries[tp]; // will create a 0 if the tp is not in the list already
503  if (indexPlus1 == 0) indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
504  muToSecondary[i] = indexPlus1 - 1;
505  }
506  }
507  LogTrace("MuonSimClassifier") <<"\t Extended classification code = " << simInfo[i].extendedClass;
508  } else { // if (tp.isNonnull())
509  simInfo[i].primaryClass = reco::MuonSimType::NotMatched;
510  simInfo[i].extendedClass = reco::ExtendedMuonSimType::ExtNotMatched;
511  }
512  } // end loop on reco muons
513 
514  writeValueMap(iEvent, muons, simInfo, "");
515 
516  if (linkToGenParticles_) {
517  edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
518  edm::RefProd<reco::GenParticleCollection> priRP(genParticles);
520  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(new edm::Association<reco::GenParticleCollection>(priRP));
521  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(new edm::Association<reco::GenParticleCollection>(secRP));
522  edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
523  fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
524  fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
525  fillPri.fill(); fillSec.fill();
526  iEvent.put(std::move(outPri), "toPrimaries");
527  iEvent.put(std::move(outSec), "toSecondaries");
528  }
529 
530 }
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
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:137
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
ProductID id() const
Definition: HandleBase.cc:15
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
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
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
ProductID id() const
Accessor for product ID.
Definition: Ref.h:259
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
Definition: MuonTrackType.h:35
edm::InputTag genParticles_
bool isGlobalMuon() const override
Definition: Muon.h:276
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &muons, MuonTrackType type, const edm::RefVector< TrackingParticleCollection > &tpColl) const
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)
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
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
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 534 of file MuonSimClassifier.cc.

References edm::helper::Filler< Map >::fill(), objects.autophobj::filler, cmsBatch::handle, edm::helper::Filler< Map >::insert(), eostools::move(), and edm::Event::put().

Referenced by produce().

538 {
539  using namespace edm;
540  using namespace std;
541  unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
542  typename edm::ValueMap<T>::Filler filler(*valMap);
543  filler.insert(handle, values.begin(), values.end());
544  filler.fill();
545  iEvent.put(std::move(valMap), label);
546 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
HLT enums.
def move(src, dest)
Definition: eostools.py:511

Member Data Documentation

edm::InputTag MuonSimClassifier::associatorLabel_
private

The Associations.

Definition at line 84 of file MuonSimClassifier.cc.

double MuonSimClassifier::decayAbsZ_
private

Definition at line 88 of file MuonSimClassifier.cc.

Referenced by produce().

double MuonSimClassifier::decayRho_
private

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

Definition at line 88 of file MuonSimClassifier.cc.

Referenced by produce().

edm::InputTag MuonSimClassifier::genParticles_
private

Definition at line 92 of file MuonSimClassifier.cc.

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

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

Definition at line 93 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().

bool MuonSimClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 91 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().

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

Definition at line 85 of file MuonSimClassifier.cc.

Referenced by produce().

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

The RECO objects.

Definition at line 75 of file MuonSimClassifier.cc.

Referenced by produce().

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

The TrackingParticle objects.

Definition at line 81 of file MuonSimClassifier.cc.

Referenced by produce().

reco::MuonTrackType MuonSimClassifier::trackType_
private

Track to use.

Definition at line 78 of file MuonSimClassifier.cc.

Referenced by MuonSimClassifier(), and produce().