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 ()
 
- Public Member Functions inherited from edm::EDProducer
 EDProducer ()
 
ModuleDescription const & moduleDescription () const
 
virtual ~EDProducer ()
 
- 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 ()
 
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, std::unordered_multimap< std::string, edm::ProductResolverIndex > const &iIndicies, std::string const &moduleLabel)
 
virtual ~ProducerBase () noexcept(false)
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
void convertCurrentProcessAlias (std::string const &processName)
 Convert "@currentProcess" in InputTag process names to the actual current process name. More...
 
 EDConsumerBase ()
 
 EDConsumerBase (EDConsumerBase const &)=delete
 
 EDConsumerBase (EDConsumerBase &&)=default
 
ProductResolverIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
std::vector< ProductResolverIndexAndSkipBit > const & itemsToGetFrom (BranchType iType) const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesWhoseProductsAreConsumed (std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
 
EDConsumerBase const & operator= (EDConsumerBase const &)=delete
 
EDConsumerBaseoperator= (EDConsumerBase &&)=default
 
bool registeredToConsume (ProductResolverIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
virtual ~EDConsumerBase () noexcept(false)
 

Private Member Functions

int convertAndPush (const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
 
int flavour (int pdgId) const
 Returns the flavour given a pdg id code. More...
 
TrackingParticleRef getTpMother (TrackingParticleRef tp)
 
virtual 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

std::string 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...
 
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
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)
 
- 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 69 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::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  associatorLabel_(iConfig.getParameter< std::string >("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  std::string trackType = iConfig.getParameter< std::string >("trackType");
140  if (trackType == "inner") trackType_ = reco::InnerTk;
141  else if (trackType == "outer") trackType_ = reco::OuterTk;
142  else if (trackType == "global") trackType_ = reco::GlobalTk;
143  else if (trackType == "segments") trackType_ = reco::Segments;
144  else throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
145  if (linkToGenParticles_) {
146  genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
147  }
148 
149  produces<edm::ValueMap<int> >();
150  produces<edm::ValueMap<int> >("ext");
151  produces<edm::ValueMap<int> >("flav");
152  produces<edm::ValueMap<int> >("hitsPdgId");
153  produces<edm::ValueMap<int> >("momPdgId");
154  produces<edm::ValueMap<int> >("momFlav");
155  produces<edm::ValueMap<int> >("momStatus");
156  produces<edm::ValueMap<int> >("gmomPdgId");
157  produces<edm::ValueMap<int> >("gmomFlav");
158  produces<edm::ValueMap<int> >("hmomFlav"); // heaviest mother flavour
159  produces<edm::ValueMap<int> >("tpId");
160  produces<edm::ValueMap<float> >("prodRho");
161  produces<edm::ValueMap<float> >("prodZ");
162  produces<edm::ValueMap<float> >("momRho");
163  produces<edm::ValueMap<float> >("momZ");
164  produces<edm::ValueMap<float> >("tpAssoQuality");
165  if (linkToGenParticles_) {
166  produces<reco::GenParticleCollection>("secondaries");
167  produces<edm::Association<reco::GenParticleCollection> >("toPrimaries");
168  produces<edm::Association<reco::GenParticleCollection> >("toSecondaries");
169  }
170 }
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.
std::string associatorLabel_
The Associations.
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
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 ( )

Definition at line 172 of file MuonMCClassifier.cc.

173 {
174 }

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

486  {
487  out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
488  if (simMom.isNonnull() && !simMom->genParticles().empty()) {
489  if (genParticles.id() != simMom->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 " << simMom->genParticles().id() << ")\n";
491  }
492  out.back().addMother(simMom->genParticles()[0]);
493  }
494  return out.size()-1;
495 }
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 467 of file MuonMCClassifier.cc.

References funct::abs().

Referenced by produce().

467  {
468  int flav = std::abs(pdgId);
469  // for quarks, leptons and bosons except gluons, take their pdgId
470  // muons and taus have themselves as flavour
471  if (flav <= 37 && flav != 21) return flav;
472  // look for barions
473  int bflav = ((flav / 1000) % 10);
474  if (bflav != 0) return bflav;
475  // look for mesons
476  int mflav = ((flav / 100) % 10);
477  if (mflav != 0) return mflav;
478  return 0;
479 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
TrackingParticleRef MuonMCClassifier::getTpMother ( TrackingParticleRef  tp)
inlineprivate

Definition at line 111 of file MuonMCClassifier.cc.

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

Referenced by produce().

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

Definition at line 177 of file MuonMCClassifier.cc.

References funct::abs(), reco::MuonToTrackingParticleAssociator::associateMuons(), associatorLabel_, edm::RefToBaseVector< T >::begin(), convertAndPush(), decayAbsZ_, decayRho_, edm::RefToBaseVector< T >::end(), Exception, edm::helper::Filler< Map >::fill(), spr::find(), flavour(), GenHFHadronMatcher_cfi::genParticles, genParticles_, genParticlesToken_, edm::Event::getByLabel(), 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_, match(), eostools::move(), RPCpg::mu, muonCut_, electronCleaner_cfi::muons, muonsToken_, gen::n, reco::OuterTk, edm::Handle< T >::product(), edm::RefToBaseVector< T >::push_back(), edm::RefVector< C, T, F >::push_back(), edm::Event::put(), trackingTruthProducer_cfi::trackingParticles, trackingParticlesToken_, trackType_, and writeValueMap().

178 {
179  edm::LogVerbatim("MuonMCClassifier") <<"\n sono in MuonMCClassifier !";
180 
182  iEvent.getByToken(muonsToken_, muons);
183 
185  iEvent.getByToken(trackingParticlesToken_, trackingParticles);
186 
188  if (linkToGenParticles_) {
189  iEvent.getByToken(genParticlesToken_, genParticles);
190  }
191 
193  iEvent.getByLabel(associatorLabel_, associatorBase);
194  const reco::MuonToTrackingParticleAssociator * assoByHits = associatorBase.product();
195 
196  reco::MuonToSimCollection recSimColl;
197  reco::SimToMuonCollection simRecColl;
198  edm::LogVerbatim("MuonMCClassifier") <<"\n ***************************************************************** ";
199  edm::LogVerbatim("MuonMCClassifier") << " RECO MUON association, type: "<< trackType_;
200  edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
201 
203  if (!hasMuonCut_) {
204  // all muons
205  for (size_t i = 0, n = muons->size(); i < n; ++i) {
206  edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
207  selMuons.push_back(rmu);
208  }
209  } else {
210  // filter, fill refvectors, associate
211  // I pass through pat::Muon so that I can access muon id selectors
212  for (size_t i = 0, n = muons->size(); i < n; ++i) {
213  edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
214  if (muonCut_(pat::Muon(rmu))) selMuons.push_back(rmu);
215  }
216  }
217 
219  for (size_t i = 0, n = trackingParticles->size(); i < n; ++i) {
220  allTPs.push_back(TrackingParticleRef(trackingParticles,i));
221  }
222 
223  assoByHits->associateMuons(recSimColl, simRecColl, selMuons, trackType_, allTPs);
224 
225  // for global muons without hits on muon detectors, look at the linked standalone muon
226  reco::MuonToSimCollection UpdSTA_recSimColl;
227  reco::SimToMuonCollection UpdSTA_simRecColl;
228  if (trackType_ == reco::GlobalTk) {
229  edm::LogVerbatim("MuonMCClassifier") <<"\n ***************************************************************** ";
230  edm::LogVerbatim("MuonMCClassifier") << " STANDALONE (UpdAtVtx) MUON association ";
231  edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
232  assoByHits->associateMuons(UpdSTA_recSimColl, UpdSTA_simRecColl, selMuons, reco::OuterTk,
233  allTPs);
234  }
235 
236  typedef reco::MuonToSimCollection::const_iterator r2s_it;
237  typedef reco::SimToMuonCollection::const_iterator s2r_it;
238 
239  size_t nmu = muons->size();
240  edm::LogVerbatim("MuonMCClassifier") <<"\n There are "<<nmu<<" reco::Muons.";
241 
242  std::vector<int> classif(nmu, 0), ext(nmu, 0);
243  std::vector<int> hitsPdgId(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
244  std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
245  std::vector<int> tpId(nmu, -1);
246  std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
247  std::vector<float> tpAssoQuality(nmu, -1);
248 
249  std::unique_ptr<reco::GenParticleCollection> secondaries; // output collection of secondary muons
250  std::map<TrackingParticleRef, int> tpToSecondaries; // map from tp to (index+1) in output collection
251  std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1); // map from input into (index) in output, -1 for null
252  if (linkToGenParticles_) secondaries.reset(new reco::GenParticleCollection());
253 
254  for(size_t i = 0; i < nmu; ++i) {
255  edm::LogVerbatim("MuonMCClassifier") <<"\n reco::Muons # "<<i;
256  edm::RefToBase<reco::Muon> mu = muons->refAt(i);
257  if (hasMuonCut_ && (std::find(selMuons.begin(), selMuons.end(), mu) == selMuons.end()) ) {
258  edm::LogVerbatim("MuonMCClassifier") <<"\t muon didn't pass the selection. classified as -99 and skipped";
259  classif[i] = -99; continue;
260  }
261 
263  edm::RefToBase<reco::Muon> muMatchBack;
264  r2s_it match = recSimColl.find(mu);
265  s2r_it matchback;
266  if (match != recSimColl.end()) {
267  edm::LogVerbatim("MuonMCClassifier") <<"\t RtS matched Ok...";
268  // match->second is vector, front is first element, first is the ref (second would be the quality)
269  tp = match->second.front().first;
270  tpId[i] = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
271  tpAssoQuality[i] = match->second.front().second;
272  s2r_it matchback = simRecColl.find(tp);
273  if (matchback != simRecColl.end()) {
274  muMatchBack = matchback->second.front().first;
275  } else {
276  edm::LogWarning("MuonMCClassifier") << "\n***WARNING: This I do NOT understand: why no match back? *** \n";
277  }
278  } else if ((trackType_ == reco::GlobalTk) &&
279  mu->isGlobalMuon()) {
280  // perform a second attempt, matching with the standalone muon
281  r2s_it matchSta = UpdSTA_recSimColl.find(mu);
282  if (matchSta != UpdSTA_recSimColl.end()) {
283  edm::LogVerbatim("MuonMCClassifier") <<"\t RtS matched Ok... from the UpdSTA_recSimColl ";
284  tp = matchSta->second.front().first;
285  tpId[i] = tp.isNonnull() ? tp.key() : -1; // we check, even if null refs should not appear here at all
286  tpAssoQuality[i] = matchSta->second.front().second;
287  s2r_it matchback = UpdSTA_simRecColl.find(tp);
288  if (matchback != UpdSTA_simRecColl.end()) {
289  muMatchBack = matchback->second.front().first;
290  } else {
291  edm::LogWarning("MuonMCClassifier") << "\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
292  }
293  }
294  }
295  if (tp.isNonnull()) {
296  bool isGhost = muMatchBack != mu;
297  if (isGhost) edm::LogVerbatim("MuonMCClassifier") <<"\t This seems a GHOST ! classif[i] will be < 0";
298 
299  hitsPdgId[i] = tp->pdgId();
300  prodRho[i] = tp->vertex().Rho();
301  prodZ[i] = tp->vertex().Z();
302  edm::LogVerbatim("MuonMCClassifier") <<"\t TP pdgId = "<<hitsPdgId[i] << ", vertex rho = " << prodRho[i] << ", z = " << prodZ[i];
303 
304  // Try to extract mother and grand mother of this muon.
305  // Unfortunately, SIM and GEN histories require diffent code :-(
306  if (!tp->genParticles().empty()) { // Muon is in GEN
307  reco::GenParticleRef genp = tp->genParticles()[0];
308  reco::GenParticleRef genMom = genp->numberOfMothers() > 0 ? genp->motherRef() : reco::GenParticleRef();
309  if (genMom.isNonnull()) {
310  momPdgId[i] = genMom->pdgId();
311  momStatus[i] = genMom->status();
312  momRho[i] = genMom->vertex().Rho(); momZ[i] = genMom->vz();
313  edm::LogVerbatim("MuonMCClassifier") << "\t Particle pdgId = "<<hitsPdgId[i] << " produced at rho = " << prodRho[i] << ", z = " << prodZ[i] << ", has GEN mother pdgId = " << momPdgId[i];
314  reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
315  if (genGMom.isNonnull()) {
316  gmomPdgId[i] = genGMom->pdgId();
317  edm::LogVerbatim("MuonMCClassifier") << "\t\t mother prod. vertex rho = " << momRho[i] << ", z = " << momZ[i] << ", grand-mom pdgId = " << gmomPdgId[i];
318  }
319  // in this case, we might want to know the heaviest mom flavour
320  for (reco::GenParticleRef nMom = genMom;
321  nMom.isNonnull() && std::abs(nMom->pdgId()) >= 100; // stop when we're no longer looking at hadrons or mesons
322  nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
323  int flav = flavour(nMom->pdgId());
324  if (hmomFlav[i] < flav) hmomFlav[i] = flav;
325  edm::LogVerbatim("MuonMCClassifier") << "\t\t backtracking flavour: mom pdgId = "<<nMom->pdgId()<< ", flavour = " << flav << ", heaviest so far = " << hmomFlav[i];
326  }
327  }
328  } else { // Muon is in SIM Only
329  TrackingParticleRef simMom = getTpMother(tp);
330  if (simMom.isNonnull()) {
331  momPdgId[i] = simMom->pdgId();
332  momRho[i] = simMom->vertex().Rho();
333  momZ[i] = simMom->vertex().Z();
334  edm::LogVerbatim("MuonMCClassifier") << "\t Particle pdgId = "<<hitsPdgId[i] << " produced at rho = " << prodRho[i] << ", z = " << prodZ[i] <<
335  ", has SIM mother pdgId = " << momPdgId[i] << " produced at rho = " << simMom->vertex().Rho() << ", z = " << simMom->vertex().Z();
336  if (!simMom->genParticles().empty()) {
337  momStatus[i] = simMom->genParticles()[0]->status();
338  reco::GenParticleRef genGMom = (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef() : reco::GenParticleRef());
339  if (genGMom.isNonnull()) gmomPdgId[i] = genGMom->pdgId();
340  edm::LogVerbatim("MuonMCClassifier") << "\t\t SIM mother is in GEN (status " << momStatus[i] << "), grand-mom id = " << gmomPdgId[i];
341  } else {
342  momStatus[i] = -1;
343  TrackingParticleRef simGMom = getTpMother(simMom);
344  if (simGMom.isNonnull()) gmomPdgId[i] = simGMom->pdgId();
345  edm::LogVerbatim("MuonMCClassifier") << "\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[i];
346  }
347  } else {
348  edm::LogVerbatim("MuonMCClassifier") << "\t Particle pdgId = "<<hitsPdgId[i] << " produced at rho = " << prodRho[i] << ", z = " << prodZ[i] << ", has NO mother!";
349  }
350  }
351  momFlav[i] = flavour(momPdgId[i]);
352  gmomFlav[i] = flavour(gmomPdgId[i]);
353 
354  // Check first IF this is a muon at all
355  if (abs(tp->pdgId()) != 13) {
356  classif[i] = isGhost ? -1 : 1;
357  ext[i] = isGhost ? -1 : 1;
358  edm::LogVerbatim("MuonMCClassifier") <<"\t This is not a muon. Sorry. classif[i] = " << classif[i];
359  continue;
360  }
361 
362  // Is this SIM muon also a GEN muon, with a mother?
363  if (!tp->genParticles().empty() && (momPdgId[i] != 0)) {
364  if (abs(momPdgId[i]) < 100 && (abs(momPdgId[i]) != 15)) {
365  classif[i] = isGhost ? -4 : 4;
366  flav[i] = (abs(momPdgId[i]) == 15 ? 15 : 13);
367  edm::LogVerbatim("MuonMCClassifier") <<"\t This seems PRIMARY MUON ! classif[i] = " << classif[i];
368  ext[i] = 10;
369  } else if (momFlav[i] == 4 || momFlav[i] == 5 || momFlav[i] == 15) {
370  classif[i] = isGhost ? -3 : 3;
371  flav[i] = momFlav[i];
372  if (momFlav[i] == 15) ext[i] = 9; // tau->mu
373  else if (momFlav[i] == 5) ext[i] = 8; // b->mu
374  else if (hmomFlav[i] == 5) ext[i] = 7; // b->c->mu
375  else ext[i] = 6; // c->mu
376  edm::LogVerbatim("MuonMCClassifier") <<"\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[i];
377  } else {
378  classif[i] = isGhost ? -2 : 2;
379  flav[i] = momFlav[i];
380  edm::LogVerbatim("MuonMCClassifier") <<"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
381  }
382  } else {
383  classif[i] = isGhost ? -2 : 2;
384  flav[i] = momFlav[i];
385  edm::LogVerbatim("MuonMCClassifier") <<"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
386  }
387  // extended classification
388  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
389  else if (abs(momPdgId[i]) < 100) ext[i] = (momFlav[i] == 15 ? 9 : 10); // primary mu, or tau->mu
390  else if (momFlav[i] == 5) ext[i] = 8; // b->mu
391  else if (momFlav[i] == 4) ext[i] = (hmomFlav[i] == 5 ? 7 : 6); // b->c->mu and c->mu
392  else if (momStatus[i] != -1) { // primary light particle
393  int id = std::abs(momPdgId[i]);
394  if (id != /*pi+*/211 && id != /*K+*/321 && id != 130 /*K0L*/) ext[i] = 5; // other light particle, possibly short-lived
395  else if (prodRho[i] < decayRho_ && std::abs(prodZ[i]) < decayAbsZ_) ext[i] = 4; // decay a la ppMuX (primary pi/K within a cylinder)
396  else ext[i] = 3; // late decay that wouldn't be in ppMuX
397  } else ext[i] = 2; // decay of non-primary particle, would not be in ppMuX
398  if (isGhost) ext[i] = -ext[i];
399 
400  if (linkToGenParticles_ && std::abs(ext[i]) >= 2) {
401  // Link to the genParticle if possible, but not decays in flight (in ppMuX they're in GEN block, but they have wrong parameters)
402  if (!tp->genParticles().empty() && std::abs(ext[i]) >= 5) {
403  if (genParticles.id() != tp->genParticles().id()) {
404  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";
405  }
406  muToPrimary[i] = tp->genParticles()[0].key();
407  } else {
408  // Don't put the same trackingParticle twice!
409  int &indexPlus1 = tpToSecondaries[tp]; // will create a 0 if the tp is not in the list already
410  if (indexPlus1 == 0) indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
411  muToSecondary[i] = indexPlus1 - 1;
412  }
413  }
414  edm::LogVerbatim("MuonMCClassifier") <<"\t Extended classification code = " << ext[i];
415  }
416  }
417 
418  writeValueMap(iEvent, muons, classif, "");
419  writeValueMap(iEvent, muons, ext, "ext");
420  writeValueMap(iEvent, muons, flav, "flav");
421  writeValueMap(iEvent, muons, tpId, "tpId");
422  writeValueMap(iEvent, muons, hitsPdgId, "hitsPdgId");
423  writeValueMap(iEvent, muons, momPdgId, "momPdgId");
424  writeValueMap(iEvent, muons, momStatus, "momStatus");
425  writeValueMap(iEvent, muons, momFlav, "momFlav");
426  writeValueMap(iEvent, muons, gmomPdgId, "gmomPdgId");
427  writeValueMap(iEvent, muons, gmomFlav, "gmomFlav");
428  writeValueMap(iEvent, muons, hmomFlav, "hmomFlav");
429  writeValueMap(iEvent, muons, prodRho, "prodRho");
430  writeValueMap(iEvent, muons, prodZ, "prodZ");
431  writeValueMap(iEvent, muons, momRho, "momRho");
432  writeValueMap(iEvent, muons, momZ, "momZ");
433  writeValueMap(iEvent, muons, tpAssoQuality, "tpAssoQuality");
434 
435  if (linkToGenParticles_) {
436  edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
437  edm::RefProd<reco::GenParticleCollection> priRP(genParticles);
439  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(new edm::Association<reco::GenParticleCollection>(priRP));
440  std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(new edm::Association<reco::GenParticleCollection>(secRP));
441  edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
442  fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
443  fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
444  fillPri.fill(); fillSec.fill();
445  iEvent.put(std::move(outPri), "toPrimaries");
446  iEvent.put(std::move(outSec), "toSecondaries");
447  }
448 }
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:122
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
ProductID id() const
Definition: HandleBase.cc:15
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
const_iterator end() const
bool isGlobalMuon() const
Definition: Muon.h:225
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:264
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:258
reco::MuonTrackType trackType_
Track to use.
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
Definition: MuonTrackType.h:35
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
std::string associatorLabel_
The Associations.
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:416
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.
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:49
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 452 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().

456 {
457  using namespace edm;
458  using namespace std;
459  unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
460  typename edm::ValueMap<T>::Filler filler(*valMap);
461  filler.insert(handle, values.begin(), values.end());
462  filler.fill();
463  iEvent.put(std::move(valMap), label);
464 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
HLT enums.
def move(src, dest)
Definition: eostools.py:510

Member Data Documentation

std::string MuonMCClassifier::associatorLabel_
private

The Associations.

Definition at line 91 of file MuonMCClassifier.cc.

Referenced by produce().

double MuonMCClassifier::decayAbsZ_
private

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

Referenced by produce().

edm::InputTag MuonMCClassifier::genParticles_
private

Definition at line 98 of file MuonMCClassifier.cc.

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

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

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

Referenced by produce().

bool MuonMCClassifier::linkToGenParticles_
private

Create a link to the generator level particles.

Definition at line 97 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().

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

Definition at line 82 of file MuonMCClassifier.cc.

Referenced by produce().

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

The RECO objects.

Definition at line 77 of file MuonMCClassifier.cc.

Referenced by produce().

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

The TrackingParticle objects.

Definition at line 88 of file MuonMCClassifier.cc.

Referenced by produce().

reco::MuonTrackType MuonMCClassifier::trackType_
private

Track to use.

Definition at line 85 of file MuonMCClassifier.cc.

Referenced by MuonMCClassifier(), and produce().