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<> edm::stream::EDProducerBase edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Public Member Functions

 MuonSimClassifier (const edm::ParameterSet &)
 
 ~MuonSimClassifier () override
 
- Public Member Functions inherited from edm::stream::EDProducer<>
 EDProducer ()=default
 
- Public Member Functions inherited from edm::stream::EDProducerBase
 EDProducerBase ()
 
ModuleDescription const & moduleDescription () const
 
 ~EDProducerBase () override
 
- Public Member Functions inherited from edm::ProducerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
std::vector< edm::ProductResolverIndex > const & indiciesForPutProducts (BranchType iBranchType) const
 
 ProducerBase ()
 
std::vector< edm::ProductResolverIndex > const & putTokenIndexToProductResolverIndex () const
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
std::function< void(BranchDescription const &)> registrationCallback () const
 used by the fwk to register list of products More...
 
void resolvePutIndicies (BranchType iBranchType, ModuleToResolverIndicies const &iIndicies, std::string const &moduleLabel)
 
virtual ~ProducerBase () noexcept(false)
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
void convertCurrentProcessAlias (std::string const &processName)
 Convert "@currentProcess" in InputTag process names to the actual current process name. More...
 
 EDConsumerBase ()
 
 EDConsumerBase (EDConsumerBase const &)=delete
 
 EDConsumerBase (EDConsumerBase &&)=default
 
ProductResolverIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
std::vector< ProductResolverIndexAndSkipBit > const & itemsToGetFrom (BranchType iType) const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesWhoseProductsAreConsumed (std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
 
EDConsumerBase const & operator= (EDConsumerBase const &)=delete
 
EDConsumerBaseoperator= (EDConsumerBase &&)=default
 
bool registeredToConsume (ProductResolverIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
virtual ~EDConsumerBase () noexcept(false)
 

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
 
- Public Types inherited from edm::stream::EDProducerBase
typedef EDProducerAdaptorBase ModuleType
 
- Public Types inherited from edm::ProducerBase
using ModuleToResolverIndicies = std::unordered_multimap< std::string, std::tuple< edm::TypeID const *, const char *, edm::ProductResolverIndex >>
 
typedef ProductRegistryHelper::TypeLabelList TypeLabelList
 
- Public Types inherited from edm::EDConsumerBase
typedef ProductLabels Labels
 
- Static Public Member Functions inherited from edm::stream::EDProducerBase
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 
- Protected Member Functions inherited from edm::EDConsumerBase
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > consumes (edm::InputTag const &tag)
 
EDGetToken consumes (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken consumes (TypeToGet const &id, edm::InputTag const &tag)
 
ConsumesCollector consumesCollector ()
 Use a ConsumesCollector to gather consumes information from helper functions. More...
 
template<typename ProductType , BranchType B = InEvent>
void consumesMany ()
 
void consumesMany (const TypeToGet &id)
 
template<BranchType B>
void consumesMany (const TypeToGet &id)
 
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > mayConsume (edm::InputTag const &tag)
 
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 

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  :
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.
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
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 570 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().

573  {
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 }
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 554 of file MuonSimClassifier.cc.

References funct::abs().

Referenced by produce().

554  {
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 }
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  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 }
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:127
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:508
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:265
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:510
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 539 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().

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 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:127
HLT enums.
def move(src, dest)
Definition: eostools.py:510

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().