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

Constructor & Destructor Documentation

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

Definition at line 128 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_.

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

182 {
183 }

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

580  {
581  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
582  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
583  if (genParticles.id() != simMom->genParticles().id()) {
584  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";
585  }
586  out.back().addMother(simMom->genParticles()[0]);
587  }
588  return out.size()-1;
589 }
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 561 of file MuonMCClassifier.cc.

References funct::abs().

Referenced by produce().

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

Definition at line 110 of file MuonMCClassifier.cc.

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

Referenced by produce().

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

Definition at line 186 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_, extraflags_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().

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

550 {
551  using namespace edm;
552  using namespace std;
553  unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
554  typename edm::ValueMap<T>::Filler filler(*valMap);
555  filler.insert(handle, values.begin(), values.end());
556  filler.fill();
557  iEvent.put(std::move(valMap), label);
558 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
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 89 of file MuonMCClassifier.cc.

double MuonMCClassifier::decayAbsZ_
private

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

Referenced by produce().

edm::InputTag MuonMCClassifier::genParticles_
private

Definition at line 97 of file MuonMCClassifier.cc.

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

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

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

Referenced by produce().

bool MuonMCClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 96 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().

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

Definition at line 90 of file MuonMCClassifier.cc.

Referenced by produce().

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

Definition at line 80 of file MuonMCClassifier.cc.

Referenced by produce().

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

The RECO objects.

Definition at line 75 of file MuonMCClassifier.cc.

Referenced by produce().

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

The TrackingParticle objects.

Definition at line 86 of file MuonMCClassifier.cc.

Referenced by produce().

reco::MuonTrackType MuonMCClassifier::trackType_
private

Track to use.

Definition at line 83 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().