CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
MuonMCClassifier Class Reference

#include <MuonAnalysis/MuonAssociators/src/MuonMCClassifier.cc>

Inheritance diagram for MuonMCClassifier:
edm::EDProducer edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Public Member Functions

 MuonMCClassifier (const edm::ParameterSet &)
 
 ~MuonMCClassifier () override
 
- Public Member Functions inherited from edm::EDProducer
 EDProducer ()
 
SerialTaskQueueglobalLuminosityBlocksQueue ()
 
SerialTaskQueueglobalRunsQueue ()
 
ModuleDescription const & moduleDescription () const
 
 ~EDProducer () 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)
 
 ~ProducerBase () noexcept(false) override
 
- 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
 
ESProxyIndex const * esGetTokenIndices (edm::Transition iTrans) const
 
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
 
ProductResolverIndexAndSkipBit uncheckedIndexFrom (EDGetToken) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
void updateLookup (eventsetup::ESRecordsToProxyIndices const &)
 
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 hasMuonCut_
 
bool linkToGenParticles_
 Create a link to the generator level particles. More...
 
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociatormuAssocToken_
 
StringCutObjectSelector< pat::MuonmuonCut_
 
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::EDProducer
typedef EDProducer 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::EDProducer
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 
static bool wantsGlobalLuminosityBlocks ()
 
static bool wantsGlobalRuns ()
 
static bool wantsStreamLuminosityBlocks ()
 
static bool wantsStreamRuns ()
 
- Protected Member Functions inherited from edm::ProducerBase
ProducesCollector producesCollector ()
 
- 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 ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes ()
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes (ESInputTag const &tag)
 
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

CLASSIFICATION: For each RECO Muon, match to SIM particle, and then:

In any case, if the TP is not preferentially matched back to the same RECO muon, label as Ghost (flip the classification)

FLAVOUR:

Definition at line 66 of file MuonMCClassifier.cc.

Constructor & Destructor Documentation

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

Definition at line 126 of file MuonMCClassifier.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_.

128  hasMuonCut_(iConfig.existsAs<std::string>("muonPreselection")),
129  muonCut_(hasMuonCut_ ? iConfig.getParameter<std::string>("muonPreselection") : ""),
131  consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
133  consumes<reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::InputTag>("associatorLabel"))),
134  decayRho_(iConfig.getParameter<double>("decayRho")),
135  decayAbsZ_(iConfig.getParameter<double>("decayAbsZ")),
136  linkToGenParticles_(iConfig.getParameter<bool>("linkToGenParticles")),
137  genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::InputTag>("genParticles") : edm::InputTag("NONE"))
138 
139 {
140  std::string trackType = iConfig.getParameter<std::string>("trackType");
141  if (trackType == "inner")
143  else if (trackType == "outer")
145  else if (trackType == "global")
147  else if (trackType == "segments")
149  else if (trackType == "glb_or_trk")
151  else
152  throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
153  if (linkToGenParticles_) {
154  genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
155  }
156 
157  produces<edm::ValueMap<int> >();
158  produces<edm::ValueMap<int> >("ext");
159  produces<edm::ValueMap<int> >("flav");
160  produces<edm::ValueMap<int> >("hitsPdgId");
161  produces<edm::ValueMap<int> >("G4processType"); // Geant process producing the particle
162  produces<edm::ValueMap<int> >("momPdgId");
163  produces<edm::ValueMap<int> >("momFlav");
164  produces<edm::ValueMap<int> >("momStatus");
165  produces<edm::ValueMap<int> >("gmomPdgId");
166  produces<edm::ValueMap<int> >("gmomFlav");
167  produces<edm::ValueMap<int> >("hmomFlav"); // heaviest mother flavour
168  produces<edm::ValueMap<int> >("tpId");
169  produces<edm::ValueMap<int> >("tpEv");
170  produces<edm::ValueMap<int> >("tpBx");
171  produces<edm::ValueMap<float> >("signp");
172  produces<edm::ValueMap<float> >("pt");
173  produces<edm::ValueMap<float> >("eta");
174  produces<edm::ValueMap<float> >("phi");
175  produces<edm::ValueMap<float> >("prodRho");
176  produces<edm::ValueMap<float> >("prodZ");
177  produces<edm::ValueMap<float> >("momRho");
178  produces<edm::ValueMap<float> >("momZ");
179  produces<edm::ValueMap<float> >("tpAssoQuality");
180  if (linkToGenParticles_) {
181  produces<reco::GenParticleCollection>("secondaries");
182  produces<edm::Association<reco::GenParticleCollection> >("toPrimaries");
183  produces<edm::Association<reco::GenParticleCollection> >("toSecondaries");
184  }
185 }
edm::InputTag genParticles_
bool linkToGenParticles_
Create a link to the generator level particles.
T getParameter(std::string const &) const
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:160
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
reco::MuonTrackType trackType_
Track to use.
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
double decayRho_
Cylinder to use to decide if a decay is early or late.
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
StringCutObjectSelector< pat::Muon > muonCut_
MuonMCClassifier::~MuonMCClassifier ( )
override

Definition at line 187 of file MuonMCClassifier.cc.

187 {}

Member Function Documentation

int MuonMCClassifier::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 608 of file MuonMCClassifier.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().

611  {
612  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
613  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
614  if (genParticles.id() != simMom->genParticles().id()) {
615  throw cms::Exception("Configuration")
616  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id " << genParticles.id()
617  << ") and the references in the TrackingParticles (id " << simMom->genParticles().id() << ")\n";
618  }
619  out.back().addMother(simMom->genParticles()[0]);
620  }
621  return out.size() - 1;
622 }
edm::InputTag genParticles_
const LorentzVector & p4() const
Four-momentum Lorentz vector. Note this is taken from the first SimTrack only.
ProductID id() const
Definition: HandleBase.cc:13
int pdgId() const
PDG ID.
int status() const
Status word.
float charge() const
Electric charge. Note this is taken from the first SimTrack only.
Point vertex() const
Parent vertex position.
ProductIndex id() const
Definition: ProductID.h:35
int MuonMCClassifier::flavour ( int  pdgId) const
private

Returns the flavour given a pdg id code.

Definition at line 589 of file MuonMCClassifier.cc.

References funct::abs().

Referenced by produce().

589  {
590  int flav = std::abs(pdgId);
591  // for quarks, leptons and bosons except gluons, take their pdgId
592  // muons and taus have themselves as flavour
593  if (flav <= 37 && flav != 21)
594  return flav;
595  // look for barions
596  int bflav = ((flav / 1000) % 10);
597  if (bflav != 0)
598  return bflav;
599  // look for mesons
600  int mflav = ((flav / 100) % 10);
601  if (mflav != 0)
602  return mflav;
603  return 0;
604 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
TrackingParticleRef MuonMCClassifier::getTpMother ( TrackingParticleRef  tp)
inlineprivate

Definition at line 109 of file MuonMCClassifier.cc.

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

Referenced by produce().

109  {
110  if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
111  return tp->parentVertex()->sourceTracks()[0];
112  } else {
113  return TrackingParticleRef();
114  }
115  }
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
edm::Ref< TrackingParticleCollection > TrackingParticleRef
void MuonMCClassifier::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
overrideprivate

Definition at line 189 of file MuonMCClassifier.cc.

References funct::abs(), reco::MuonToTrackingParticleAssociator::associateMuons(), edm::RefToBaseVector< T >::begin(), convertAndPush(), decayAbsZ_, decayRho_, edm::RefToBaseVector< T >::end(), PVValHelper::eta, Exception, edm::helper::Filler< Map >::fill(), spr::find(), flavour(), EgammaValidation_cff::genp, genParticles2HepMC_cfi::genParticles, genParticles_, genParticlesToken_, edm::Event::getByToken(), getTpMother(), reco::GlobalTk, hasMuonCut_, 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(), eostools::move(), amptDefaultParameters_cff::mu, muAssocToken_, muonCut_, PDWG_BPHSkim_cff::muons, muonsToken_, dqmiodumpmetadata::n, reco::OuterTk, phi, edm::Handle< T >::product(), DiDispStaMuonMonitor_cfi::pt, edm::RefToBaseVector< T >::push_back(), edm::RefVector< C, T, F >::push_back(), edm::Event::put(), muonClassificationByHits_cfi::trackingParticles, trackingParticlesToken_, trackType_, and writeValueMap().

189  {
191  iEvent.getByToken(muonsToken_, muons);
192 
194  iEvent.getByToken(trackingParticlesToken_, trackingParticles);
195 
197  if (linkToGenParticles_) {
198  iEvent.getByToken(genParticlesToken_, genParticles);
199  }
200 
202  iEvent.getByToken(muAssocToken_, associatorBase);
203  const reco::MuonToTrackingParticleAssociator *assoByHits = associatorBase.product();
204 
205  reco::MuonToSimCollection recSimColl;
206  reco::SimToMuonCollection simRecColl;
207  edm::LogVerbatim("MuonMCClassifier") << "\n ***************************************************************** ";
208  edm::LogVerbatim("MuonMCClassifier") << " RECO MUON association, type: " << trackType_;
209  edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
210 
212  if (!hasMuonCut_) {
213  // all muons
214  for (size_t i = 0, n = muons->size(); i < n; ++i) {
215  edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
216  selMuons.push_back(rmu);
217  }
218  } else {
219  // filter, fill refvectors, associate
220  // I pass through pat::Muon so that I can access muon id selectors
221  for (size_t i = 0, n = muons->size(); i < n; ++i) {
222  edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
223  if (muonCut_(pat::Muon(rmu)))
224  selMuons.push_back(rmu);
225  }
226  }
227 
229  for (size_t i = 0, n = trackingParticles->size(); i < n; ++i) {
230  allTPs.push_back(TrackingParticleRef(trackingParticles, i));
231  }
232 
233  assoByHits->associateMuons(recSimColl, simRecColl, selMuons, trackType_, allTPs);
234 
235  // for global muons without hits on muon detectors, look at the linked standalone muon
236  reco::MuonToSimCollection UpdSTA_recSimColl;
237  reco::SimToMuonCollection UpdSTA_simRecColl;
238  if (trackType_ == reco::GlobalTk) {
239  edm::LogVerbatim("MuonMCClassifier") << "\n ***************************************************************** ";
240  edm::LogVerbatim("MuonMCClassifier") << " STANDALONE (UpdAtVtx) MUON association ";
241  edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
242  assoByHits->associateMuons(UpdSTA_recSimColl, UpdSTA_simRecColl, selMuons, reco::OuterTk, allTPs);
243  }
244 
245  typedef reco::MuonToSimCollection::const_iterator r2s_it;
246  typedef reco::SimToMuonCollection::const_iterator s2r_it;
247 
248  size_t nmu = muons->size();
249  edm::LogVerbatim("MuonMCClassifier") << "\n There are " << nmu << " reco::Muons.";
250 
251  std::vector<int> classif(nmu, 0), ext(nmu, 0);
252  std::vector<int> hitsPdgId(nmu, 0), G4processType(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
253  std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
254  std::vector<int> tpId(nmu, -1), tpBx(nmu, 999), tpEv(nmu, 999);
255  std::vector<float> signp(nmu, 0.0), pt(nmu, 0.0), eta(nmu, -99.), phi(nmu, -99.);
256  std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
257  std::vector<float> tpAssoQuality(nmu, -1);
258 
259  std::unique_ptr<reco::GenParticleCollection> secondaries; // output collection of secondary muons
260  std::map<TrackingParticleRef, int> tpToSecondaries; // map from tp to (index+1) in output collection
261  std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1); // map from input into (index) in output, -1 for null
263  secondaries.reset(new reco::GenParticleCollection());
264 
265  // loop on reco muons
266  for (size_t i = 0; i < nmu; ++i) {
267  edm::RefToBase<reco::Muon> mu = muons->refAt(i);
268  if (hasMuonCut_ && (std::find(selMuons.begin(), selMuons.end(), mu) == selMuons.end())) {
269  LogTrace("MuonMCClassifier") << "\n reco::Muon # " << i
270  << "didn't pass the selection. classified as -99 and skipped";
271  classif[i] = -99;
272  continue;
273  } else
274  edm::LogVerbatim("MuonMCClassifier") << "\n reco::Muon # " << i;
275 
277  edm::RefToBase<reco::Muon> muMatchBack;
278  r2s_it match = recSimColl.find(mu);
279  s2r_it matchback;
280  if (match != recSimColl.end()) {
281  // match->second is vector, front is first element, first is the ref (second would be the quality)
282  tp = match->second.front().first;
283  tpId[i] = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
284  tpAssoQuality[i] = match->second.front().second;
285  s2r_it matchback = simRecColl.find(tp);
286  if (matchback != simRecColl.end()) {
287  muMatchBack = matchback->second.front().first;
288  } else {
289  edm::LogWarning("MuonMCClassifier") << "\n***WARNING: This I do NOT understand: why no match back? *** \n";
290  }
291  } else if ((trackType_ == reco::GlobalTk) && mu->isGlobalMuon()) {
292  // perform a second attempt, matching with the standalone muon
293  r2s_it matchSta = UpdSTA_recSimColl.find(mu);
294  if (matchSta != UpdSTA_recSimColl.end()) {
295  tp = matchSta->second.front().first;
296  tpId[i] = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
297  tpAssoQuality[i] = matchSta->second.front().second;
298  s2r_it matchback = UpdSTA_simRecColl.find(tp);
299  if (matchback != UpdSTA_simRecColl.end()) {
300  muMatchBack = matchback->second.front().first;
301  } else {
302  edm::LogWarning("MuonMCClassifier")
303  << "\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
304  }
305  }
306  } else {
307  edm::LogVerbatim("MuonMCClassifier") << "\t No matching TrackingParticle is found ";
308  }
309 
310  if (tp.isNonnull()) {
311  bool isGhost = muMatchBack != mu;
312  if (isGhost)
313  edm::LogVerbatim("MuonMCClassifier") << "\t *** This seems a Duplicate muon ! classif[i] will be < 0 ***";
314 
315  // identify signal and pileup TP
316  tpBx[i] = tp->eventId().bunchCrossing();
317  tpEv[i] = tp->eventId().event();
318 
319  hitsPdgId[i] = tp->pdgId();
320  prodRho[i] = tp->vertex().Rho();
321  prodZ[i] = tp->vertex().Z();
322 
323  // added info on GEANT process producing the TrackingParticle
324  const std::vector<SimVertex> &G4Vs = tp->parentVertex()->g4Vertices();
325  G4processType[i] = G4Vs[0].processType();
326 
327  signp[i] = tp->charge() * tp->p();
328  pt[i] = tp->pt();
329  eta[i] = tp->eta();
330  phi[i] = tp->phi();
331 
332  // Try to extract mother and grand mother of this muon.
333  // Unfortunately, SIM and GEN histories require diffent code :-(
334  if (!tp->genParticles().empty()) { // Muon is in GEN
335  reco::GenParticleRef genp = tp->genParticles()[0];
336  reco::GenParticleRef genMom = genp->numberOfMothers() > 0 ? genp->motherRef() : reco::GenParticleRef();
337  reco::GenParticleRef mMom = genMom;
338 
339  if (genMom.isNonnull()) {
340  if (genMom->pdgId() != tp->pdgId()) {
341  momPdgId[i] = genMom->pdgId();
342  momStatus[i] = genMom->status();
343  momRho[i] = genMom->vertex().Rho();
344  momZ[i] = genMom->vz();
345  } else {
346  // if mother has the same identity look backwards for the real mother (it may happen in radiative decays)
347  int jm = 0;
348  while (mMom->pdgId() == tp->pdgId()) {
349  jm++;
350 
351  if (mMom->numberOfMothers() > 0) {
352  mMom = mMom->motherRef();
353  }
354  LogTrace("MuonMCClassifier") << "\t\t backtracking mother " << jm << ", pdgId = " << mMom->pdgId()
355  << ", status= " << mMom->status();
356  }
357  genMom = mMom; // redefine genMom
358  momPdgId[i] = genMom->pdgId();
359  momStatus[i] = genMom->status();
360  momRho[i] = genMom->vertex().Rho();
361  momZ[i] = genMom->vz();
362  }
363  edm::LogVerbatim("MuonMCClassifier")
364  << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
365  << "(" << tpEv[i] << "," << tpBx[i] << ")"
366  << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
367  << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
368  << ", (GEANT4 process = " << G4processType[i] << ")"
369  << "\n\t has GEN mother pdgId = " << momPdgId[i] << " (status = " << momStatus[i] << ")";
370 
371  reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
372 
373  if (genGMom.isNonnull()) {
374  gmomPdgId[i] = genGMom->pdgId();
375  edm::LogVerbatim("MuonMCClassifier") << "\t\t mother prod. vertex rho = " << momRho[i]
376  << ", z = " << momZ[i] << ", grand-mom pdgId = " << gmomPdgId[i];
377  }
378  // in this case, we might want to know the heaviest mom flavour
379  for (reco::GenParticleRef nMom = genMom;
380  nMom.isNonnull() &&
381  std::abs(nMom->pdgId()) >= 100; // stop when we're no longer looking at hadrons or mesons
382  nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
383  int flav = flavour(nMom->pdgId());
384  if (hmomFlav[i] < flav)
385  hmomFlav[i] = flav;
386  edm::LogVerbatim("MuonMCClassifier") << "\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
387  << ", flavour = " << flav << ", heaviest so far = " << hmomFlav[i];
388  }
389  } // if (genMom.isNonnull())
390 
391  else { // mother is null ??
392  edm::LogWarning("MuonMCClassifier")
393  << "\t GenParticle with pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
394  << "(" << tpEv[i] << "," << tpBx[i] << ")"
395  << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
396  << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
397  << ", (GEANT4 process = " << G4processType[i] << ")"
398  << "\n\t has NO mother!";
399  }
400 
401  } else { // Muon is in SIM Only
402  TrackingParticleRef simMom = getTpMother(tp);
403  if (simMom.isNonnull()) {
404  momPdgId[i] = simMom->pdgId();
405  momRho[i] = simMom->vertex().Rho();
406  momZ[i] = simMom->vertex().Z();
407  edm::LogVerbatim("MuonMCClassifier")
408  << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
409  << "(" << tpEv[i] << "," << tpBx[i] << ")"
410  << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
411  << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
412  << ", (GEANT4 process = " << G4processType[i] << ")"
413  << "\n\t has SIM mother pdgId = " << momPdgId[i] << " produced at rho = " << simMom->vertex().Rho()
414  << ", z = " << simMom->vertex().Z();
415 
416  if (!simMom->genParticles().empty()) {
417  momStatus[i] = simMom->genParticles()[0]->status();
418  reco::GenParticleRef genGMom =
419  (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
421  if (genGMom.isNonnull())
422  gmomPdgId[i] = genGMom->pdgId();
423  edm::LogVerbatim("MuonMCClassifier")
424  << "\t\t SIM mother is in GEN (status " << momStatus[i] << "), grand-mom id = " << gmomPdgId[i];
425  } else {
426  momStatus[i] = -1;
427  TrackingParticleRef simGMom = getTpMother(simMom);
428  if (simGMom.isNonnull())
429  gmomPdgId[i] = simGMom->pdgId();
430  edm::LogVerbatim("MuonMCClassifier") << "\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[i];
431  }
432  } else {
433  edm::LogVerbatim("MuonMCClassifier")
434  << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
435  << "(" << tpEv[i] << "," << tpBx[i] << ")"
436  << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
437  << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
438  << ", (GEANT4 process = " << G4processType[i] << ")"
439  << "\n\t has NO mother!";
440  }
441  }
442  momFlav[i] = flavour(momPdgId[i]);
443  gmomFlav[i] = flavour(gmomPdgId[i]);
444 
445  // Check first IF this is a muon at all
446  if (abs(tp->pdgId()) != 13) {
447  if (abs(tp->pdgId()) == 11) {
448  classif[i] = isGhost ? -11 : 11;
449  ext[i] = isGhost ? -11 : 11;
450  edm::LogVerbatim("MuonMCClassifier") << "\t This is electron/positron. classif[i] = " << classif[i];
451  } else {
452  classif[i] = isGhost ? -1 : 1;
453  ext[i] = isGhost ? -1 : 1;
454  edm::LogVerbatim("MuonMCClassifier") << "\t This is not a muon. Sorry. classif[i] = " << classif[i];
455  }
456 
457  continue;
458  }
459 
460  // Is this SIM muon also a GEN muon, with a mother?
461  if (!tp->genParticles().empty() && (momPdgId[i] != 0)) {
462  if (abs(momPdgId[i]) < 100 && (abs(momPdgId[i]) != 15)) {
463  classif[i] = isGhost ? -4 : 4;
464  flav[i] = 13;
465  ext[i] = 10;
466  edm::LogVerbatim("MuonMCClassifier") << "\t This seems PRIMARY MUON ! classif[i] = " << classif[i];
467  } else if (momFlav[i] == 4 || momFlav[i] == 5 || momFlav[i] == 15) {
468  classif[i] = isGhost ? -3 : 3;
469  flav[i] = momFlav[i];
470  if (momFlav[i] == 15)
471  ext[i] = 9; // tau->mu
472  else if (momFlav[i] == 5)
473  ext[i] = 8; // b->mu
474  else if (hmomFlav[i] == 5)
475  ext[i] = 7; // b->c->mu or b->tau->mu
476  else
477  ext[i] = 6; // c->mu
478  edm::LogVerbatim("MuonMCClassifier") << "\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[i];
479  } else {
480  classif[i] = isGhost ? -2 : 2;
481  flav[i] = momFlav[i];
482  edm::LogVerbatim("MuonMCClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
483  }
484  } else {
485  classif[i] = isGhost ? -2 : 2;
486  flav[i] = momFlav[i];
487  edm::LogVerbatim("MuonMCClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
488  }
489  // extended classification
490  if (momPdgId[i] == 0)
491  ext[i] = 2; // if it has no mom, it's not a primary particle so it won't be in ppMuX
492  else if (abs(momPdgId[i]) < 100)
493  ext[i] = (momFlav[i] == 15 ? 9 : 10); // primary mu, or tau->mu
494  else if (momFlav[i] == 5)
495  ext[i] = 8; // b->mu
496  else if (momFlav[i] == 4)
497  ext[i] = (hmomFlav[i] == 5 ? 7 : 6); // b->c->mu and c->mu
498  else if (momStatus[i] != -1) { // primary light particle
499  int id = std::abs(momPdgId[i]);
500  if (id != /*pi+*/ 211 && id != /*K+*/ 321 && id != 130 /*K0L*/)
501  ext[i] = 5; // other light particle, possibly short-lived
502  else if (prodRho[i] < decayRho_ && std::abs(prodZ[i]) < decayAbsZ_)
503  ext[i] = 4; // decay a la ppMuX (primary pi/K within a cylinder)
504  else
505  ext[i] = 3; // late decay that wouldn't be in ppMuX
506  } else
507  ext[i] = 2; // decay of non-primary particle, would not be in ppMuX
508  if (isGhost)
509  ext[i] = -ext[i];
510 
511  if (linkToGenParticles_ && std::abs(ext[i]) >= 2) {
512  // Link to the genParticle if possible, but not decays in flight (in ppMuX they're in GEN block, but they have wrong parameters)
513  if (!tp->genParticles().empty() && std::abs(ext[i]) >= 5) {
514  if (genParticles.id() != tp->genParticles().id()) {
515  throw cms::Exception("Configuration")
516  << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id "
517  << genParticles.id() << ") and the references in the TrackingParticles (id " << tp->genParticles().id()
518  << ")\n";
519  }
520  muToPrimary[i] = tp->genParticles()[0].key();
521  } else {
522  // Don't put the same trackingParticle twice!
523  int &indexPlus1 = tpToSecondaries[tp]; // will create a 0 if the tp is not in the list already
524  if (indexPlus1 == 0)
525  indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
526  muToSecondary[i] = indexPlus1 - 1;
527  }
528  }
529  edm::LogVerbatim("MuonMCClassifier") << "\t Extended classification code = " << ext[i];
530  } // if (tp.isNonnull())
531  } // end loop on reco muons
532 
533  writeValueMap(iEvent, muons, classif, "");
534  writeValueMap(iEvent, muons, ext, "ext");
535  writeValueMap(iEvent, muons, flav, "flav");
536  writeValueMap(iEvent, muons, tpId, "tpId");
537  writeValueMap(iEvent, muons, tpBx, "tpBx");
538  writeValueMap(iEvent, muons, tpEv, "tpEv");
539  writeValueMap(iEvent, muons, hitsPdgId, "hitsPdgId");
540  writeValueMap(iEvent, muons, G4processType, "G4processType");
541  writeValueMap(iEvent, muons, momPdgId, "momPdgId");
542  writeValueMap(iEvent, muons, momStatus, "momStatus");
543  writeValueMap(iEvent, muons, momFlav, "momFlav");
544  writeValueMap(iEvent, muons, gmomPdgId, "gmomPdgId");
545  writeValueMap(iEvent, muons, gmomFlav, "gmomFlav");
546  writeValueMap(iEvent, muons, hmomFlav, "hmomFlav");
547  writeValueMap(iEvent, muons, signp, "signp");
548  writeValueMap(iEvent, muons, pt, "pt");
549  writeValueMap(iEvent, muons, eta, "eta");
550  writeValueMap(iEvent, muons, phi, "phi");
551  writeValueMap(iEvent, muons, prodRho, "prodRho");
552  writeValueMap(iEvent, muons, prodZ, "prodZ");
553  writeValueMap(iEvent, muons, momRho, "momRho");
554  writeValueMap(iEvent, muons, momZ, "momZ");
555  writeValueMap(iEvent, muons, tpAssoQuality, "tpAssoQuality");
556 
557  if (linkToGenParticles_) {
558  edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
559  edm::RefProd<reco::GenParticleCollection> priRP(genParticles);
561  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(
563  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(
565  edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
566  fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
567  fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
568  fillPri.fill();
569  fillSec.fill();
570  iEvent.put(std::move(outPri), "toPrimaries");
571  iEvent.put(std::move(outSec), "toSecondaries");
572  }
573 }
edm::InputTag genParticles_
bool linkToGenParticles_
Create a link to the generator level particles.
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
Definition: MuonTrackType.h:37
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
genp
produce generated paricles in acceptance #
ProductID id() const
Definition: HandleBase.cc:13
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
const_iterator end() const
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:250
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
reco::MuonTrackType trackType_
Track to use.
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
Definition: MuonTrackType.h:38
bool isGlobalMuon() const override
Definition: Muon.h:298
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
TrackingParticleRef getTpMother(TrackingParticleRef tp)
#define LogTrace(id)
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
T const * product() const
Definition: Handle.h:69
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.
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
const_iterator begin() const
double decayRho_
Cylinder to use to decide if a decay is early or late.
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
void push_back(const RefToBase< T > &)
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Definition: RefVector.h:67
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
Definition: memstream.h:15
int flavour(int pdgId) const
Returns the flavour given a pdg id code.
Analysis-level muon class.
Definition: Muon.h:51
edm::Ref< TrackingParticleCollection > TrackingParticleRef
def move(src, dest)
Definition: eostools.py:511
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
StringCutObjectSelector< pat::Muon > muonCut_
template<typename T >
void MuonMCClassifier::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 576 of file MuonMCClassifier.cc.

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

Referenced by produce().

579  {
580  using namespace edm;
581  using namespace std;
582  unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
583  typename edm::ValueMap<T>::Filler filler(*valMap);
584  filler.insert(handle, values.begin(), values.end());
585  filler.fill();
586  iEvent.put(std::move(valMap), label);
587 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
char const * label
HLT enums.
def move(src, dest)
Definition: eostools.py:511

Member Data Documentation

edm::InputTag MuonMCClassifier::associatorLabel_
private

The Associations.

Definition at line 88 of file MuonMCClassifier.cc.

double MuonMCClassifier::decayAbsZ_
private

Definition at line 92 of file MuonMCClassifier.cc.

Referenced by produce().

double MuonMCClassifier::decayRho_
private

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

Definition at line 92 of file MuonMCClassifier.cc.

Referenced by produce().

edm::InputTag MuonMCClassifier::genParticles_
private

Definition at line 96 of file MuonMCClassifier.cc.

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

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

Definition at line 97 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().

bool MuonMCClassifier::hasMuonCut_
private

A preselection cut for the muon. I pass through pat::Muon so that I can access muon id selectors

Definition at line 78 of file MuonMCClassifier.cc.

Referenced by produce().

bool MuonMCClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 95 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().

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

Definition at line 89 of file MuonMCClassifier.cc.

Referenced by produce().

StringCutObjectSelector<pat::Muon> MuonMCClassifier::muonCut_
private

Definition at line 79 of file MuonMCClassifier.cc.

Referenced by produce().

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

The RECO objects.

Definition at line 74 of file MuonMCClassifier.cc.

Referenced by produce().

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

The TrackingParticle objects.

Definition at line 85 of file MuonMCClassifier.cc.

Referenced by produce().

reco::MuonTrackType MuonMCClassifier::trackType_
private

Track to use.

Definition at line 82 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().