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 ()
 
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)
 
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
 
ProductResolverIndexAndSkipBit uncheckedIndexFrom (EDGetToken) 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 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::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

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 70 of file MuonMCClassifier.cc.

Constructor & Destructor Documentation

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

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

131  :
133  hasMuonCut_(iConfig.existsAs<std::string>("muonPreselection")),
134  muonCut_(hasMuonCut_ ? iConfig.getParameter<std::string>("muonPreselection") : ""),
135  trackingParticlesToken_(consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
136  muAssocToken_(consumes<reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::InputTag>("associatorLabel"))),
137  decayRho_(iConfig.getParameter<double>("decayRho")),
138  decayAbsZ_(iConfig.getParameter<double>("decayAbsZ")),
139  linkToGenParticles_(iConfig.getParameter<bool>("linkToGenParticles")),
140  genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::InputTag>("genParticles") : edm::InputTag("NONE"))
141 
142 {
143  std::string trackType = iConfig.getParameter< std::string >("trackType");
144  if (trackType == "inner") trackType_ = reco::InnerTk;
145  else if (trackType == "outer") trackType_ = reco::OuterTk;
146  else if (trackType == "global") trackType_ = reco::GlobalTk;
147  else if (trackType == "segments") trackType_ = reco::Segments;
148  else if (trackType == "glb_or_trk") trackType_ = reco::GlbOrTrk;
149  else throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
150  if (linkToGenParticles_) {
151  genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
152  }
153 
154  produces<edm::ValueMap<int> >();
155  produces<edm::ValueMap<int> >("ext");
156  produces<edm::ValueMap<int> >("flav");
157  produces<edm::ValueMap<int> >("hitsPdgId");
158  produces<edm::ValueMap<int> >("G4processType"); // Geant process producing the particle
159  produces<edm::ValueMap<int> >("momPdgId");
160  produces<edm::ValueMap<int> >("momFlav");
161  produces<edm::ValueMap<int> >("momStatus");
162  produces<edm::ValueMap<int> >("gmomPdgId");
163  produces<edm::ValueMap<int> >("gmomFlav");
164  produces<edm::ValueMap<int> >("hmomFlav"); // heaviest mother flavour
165  produces<edm::ValueMap<int> >("tpId");
166  produces<edm::ValueMap<int> >("tpEv");
167  produces<edm::ValueMap<int> >("tpBx");
168  produces<edm::ValueMap<float> >("signp");
169  produces<edm::ValueMap<float> >("pt");
170  produces<edm::ValueMap<float> >("eta");
171  produces<edm::ValueMap<float> >("phi");
172  produces<edm::ValueMap<float> >("prodRho");
173  produces<edm::ValueMap<float> >("prodZ");
174  produces<edm::ValueMap<float> >("momRho");
175  produces<edm::ValueMap<float> >("momZ");
176  produces<edm::ValueMap<float> >("tpAssoQuality");
177  if (linkToGenParticles_) {
178  produces<reco::GenParticleCollection>("secondaries");
179  produces<edm::Association<reco::GenParticleCollection> >("toPrimaries");
180  produces<edm::Association<reco::GenParticleCollection> >("toSecondaries");
181  }
182 }
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:186
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 184 of file MuonMCClassifier.cc.

185 {
186 }

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

583  {
584  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
585  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
586  if (genParticles.id() != simMom->genParticles().id()) {
587  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";
588  }
589  out.back().addMother(simMom->genParticles()[0]);
590  }
591  return out.size()-1;
592 }
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: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.
Point vertex() const
Parent vertex position.
ProductIndex id() const
Definition: ProductID.h:38
int MuonMCClassifier::flavour ( int  pdgId) const
private

Returns the flavour given a pdg id code.

Definition at line 564 of file MuonMCClassifier.cc.

References funct::abs().

Referenced by produce().

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

Definition at line 113 of file MuonMCClassifier.cc.

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

Referenced by produce().

113  {
114  if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
115  return tp->parentVertex()->sourceTracks()[0];
116  } else {
117  return TrackingParticleRef();
118  }
119  }
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
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(), GenHFHadronMatcher_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(), RPCpg::mu, muAssocToken_, muonCut_, nano_cff::muons, muonsToken_, gen::n, reco::OuterTk, phi, edm::Handle< T >::product(), EnergyCorrector::pt, edm::RefToBaseVector< T >::push_back(), edm::RefVector< C, T, F >::push_back(), edm::Event::put(), trackingTruthProducer_cfi::trackingParticles, trackingParticlesToken_, trackType_, and writeValueMap().

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

553 {
554  using namespace edm;
555  using namespace std;
556  unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
557  typename edm::ValueMap<T>::Filler filler(*valMap);
558  filler.insert(handle, values.begin(), values.end());
559  filler.fill();
560  iEvent.put(std::move(valMap), label);
561 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:136
HLT enums.
def move(src, dest)
Definition: eostools.py:510

Member Data Documentation

edm::InputTag MuonMCClassifier::associatorLabel_
private

The Associations.

Definition at line 92 of file MuonMCClassifier.cc.

double MuonMCClassifier::decayAbsZ_
private

Definition at line 96 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 96 of file MuonMCClassifier.cc.

Referenced by produce().

edm::InputTag MuonMCClassifier::genParticles_
private

Definition at line 100 of file MuonMCClassifier.cc.

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

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

Definition at line 101 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 82 of file MuonMCClassifier.cc.

Referenced by produce().

bool MuonMCClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 99 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().

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

Definition at line 93 of file MuonMCClassifier.cc.

Referenced by produce().

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

Definition at line 83 of file MuonMCClassifier.cc.

Referenced by produce().

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

The RECO objects.

Definition at line 78 of file MuonMCClassifier.cc.

Referenced by produce().

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

The TrackingParticle objects.

Definition at line 89 of file MuonMCClassifier.cc.

Referenced by produce().

reco::MuonTrackType MuonMCClassifier::trackType_
private

Track to use.

Definition at line 86 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().