102 const std::vector<T> &
values,
106 if (tp.
isNonnull() && tp->parentVertex().
isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
107 return tp->parentVertex()->sourceTracks()[0];
126 muAssocToken_(consumes<
reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<
edm::InputTag>(
"associatorLabel"))),
127 decayRho_(iConfig.getParameter<double>(
"decayRho")),
128 decayAbsZ_(iConfig.getParameter<double>(
"decayAbsZ")),
139 else throw cms::Exception(
"Configuration") <<
"Track type '" << trackType <<
"' not supported.\n";
144 produces<edm::ValueMap<reco::MuonSimInfo> >();
146 produces<reco::GenParticleCollection>(
"secondaries");
147 produces<edm::Association<reco::GenParticleCollection> >(
"toPrimaries");
148 produces<edm::Association<reco::GenParticleCollection> >(
"toSecondaries");
159 "\t Particle pdgId = " << simInfo.
pdgId <<
160 ", (Event,Bx) = "<<
"(" << simInfo.
tpEvent <<
"," << simInfo.
tpBX <<
")" <<
161 "\n\t q*p = " << simInfo.
charge*simInfo.
p4.P() <<
162 ", pT = " << simInfo.
p4.pt() <<
", eta = " << simInfo.
p4.eta() <<
", phi = " << simInfo.
p4.phi() <<
163 "\n\t produced at vertex rho = " << simInfo.
vertex.Rho() <<
", z = " << simInfo.
vertex.Z() <<
187 LogTrace(
"MuonSimClassifier") <<
"\n ***************************************************************** ";
189 LogTrace(
"MuonSimClassifier") <<
" ***************************************************************** \n";
192 for (
size_t i = 0,
n = muons->size();
i <
n; ++
i) {
197 for (
size_t i = 0, n = trackingParticles->size();
i <
n; ++
i) {
207 LogTrace(
"MuonSimClassifier") <<
"\n ***************************************************************** ";
208 LogTrace(
"MuonSimClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
209 LogTrace(
"MuonSimClassifier") <<
" ***************************************************************** \n";
213 typedef reco::MuonToSimCollection::const_iterator r2s_it;
214 typedef reco::SimToMuonCollection::const_iterator s2r_it;
216 size_t nmu = muons->size();
217 LogTrace(
"MuonSimClassifier") <<
"\n There are "<<nmu<<
" reco::Muons.";
219 std::vector<reco::MuonSimInfo> simInfo;
221 std::unique_ptr<reco::GenParticleCollection> secondaries;
222 std::map<TrackingParticleRef, int> tpToSecondaries;
223 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1);
227 for(
size_t i = 0;
i < nmu; ++
i) {
229 LogTrace(
"MuonSimClassifier") <<
"\n reco::Muon # "<<
i;
233 r2s_it
match = recSimColl.find(allMuons.
at(
i));
235 if (match != recSimColl.end()) {
237 tp = match->second.front().first;
239 simInfo[
i].tpAssoQuality = match->second.front().second;
240 s2r_it matchback = simRecColl.find(tp);
241 if (matchback != simRecColl.end()) {
242 muMatchBack = matchback->second.front().first;
244 LogTrace(
"MuonSimClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back? *** \n";
249 r2s_it matchSta = updSTA_recSimColl.find(allMuons.
at(
i));
250 if (matchSta != updSTA_recSimColl.end()) {
251 tp = matchSta->second.front().first;
253 simInfo[
i].tpAssoQuality = matchSta->second.front().second;
254 s2r_it matchback = updSTA_simRecColl.find(tp);
255 if (matchback != updSTA_simRecColl.end()) {
256 muMatchBack = matchback->second.front().first;
259 "\n***WARNING: This I do NOT understand: why no match back in updSTA? *** \n";
263 LogTrace(
"MuonSimClassifier") <<
"\t No matching TrackingParticle is found ";
268 bool isGhost = muMatchBack != allMuons.
at(
i);
269 if (isGhost)
LogTrace(
"MuonSimClassifier") <<
"\t *** This seems a Duplicate muon ! classif[i] will be < 0 ***";
272 simInfo[
i].tpBX = tp->eventId().bunchCrossing();
273 simInfo[
i].tpEvent = tp->eventId().event();
275 simInfo[
i].pdgId = tp->pdgId();
276 simInfo[
i].vertex = tp->vertex();
279 const std::vector<SimVertex> & g4Vs = tp->parentVertex()->g4Vertices();
280 simInfo[
i].g4processType = g4Vs[0].processType();
282 simInfo[
i].charge = tp->charge();
283 simInfo[
i].p4 = tp->p4();
287 if (!tp->genParticles().empty()) {
293 if (genMom->pdgId() != tp->pdgId()) {
294 simInfo[
i].motherPdgId = genMom->pdgId();
295 simInfo[
i].motherStatus = genMom->status();
296 simInfo[
i].motherVertex = genMom->vertex();
300 while (mMom->pdgId() == tp->pdgId()) {
302 if (mMom->numberOfMothers() > 0) {
303 mMom = mMom->motherRef();
305 LogTrace(
"MuonSimClassifier") <<
"\t No Mother is found ";
310 <<
"\t\t backtracking mother "<<jm<<
", pdgId = "<<mMom->pdgId()<<
", status= " <<mMom->status();
313 simInfo[
i].motherPdgId = genMom->pdgId();
314 simInfo[
i].motherStatus = genMom->status();
315 simInfo[
i].motherVertex = genMom->vertex();
319 "\t has GEN mother pdgId = " << simInfo[
i].motherPdgId <<
320 " (status = " << simInfo[
i].motherStatus <<
")";
325 simInfo[
i].grandMotherPdgId = genGMom->pdgId();
327 "\t\t mother prod. vertex rho = " << simInfo[
i].motherVertex.Rho() <<
", z = " << simInfo[
i].motherVertex.Z() <<
328 ", grand-mom pdgId = " << simInfo[
i].grandMotherPdgId;
334 int flav =
flavour(nMom->pdgId());
335 if (simInfo[i].heaviestMotherFlavour < flav) simInfo[
i].heaviestMotherFlavour = flav;
337 <<
"\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
338 <<
", flavour = " << flav <<
", heaviest so far = " << simInfo[
i].heaviestMotherFlavour;
342 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
347 simInfo[
i].motherPdgId = simMom->pdgId();
348 simInfo[
i].motherVertex = simMom->vertex();
351 "\t has SIM mother pdgId = " << simInfo[
i].motherPdgId <<
352 " produced at rho = " << simMom->vertex().Rho() <<
", z = " << simMom->vertex().Z();
354 if (!simMom->genParticles().empty()) {
355 simInfo[
i].motherStatus = simMom->genParticles()[0]->status();
357 simMom->genParticles()[0]->motherRef() :
359 if (genGMom.
isNonnull()) simInfo[i].grandMotherPdgId = genGMom->pdgId();
361 "\t\t SIM mother is in GEN (status " << simInfo[
i].motherStatus <<
362 "), grand-mom id = " << simInfo[
i].grandMotherPdgId;
364 simInfo[
i].motherStatus = -1;
366 if (simGMom.
isNonnull()) simInfo[i].grandMotherPdgId = simGMom->pdgId();
368 "\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[
i].grandMotherPdgId;
372 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
375 simInfo[
i].motherFlavour =
flavour(simInfo[
i].motherPdgId);
376 simInfo[
i].grandMotherFlavour =
flavour(simInfo[
i].grandMotherPdgId);
383 LogTrace(
"MuonSimClassifier") <<
"\t This is electron/positron. classif[i] = " << simInfo[
i].primaryClass;
387 LogTrace(
"MuonSimClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << simInfo[
i].primaryClass;
393 if (!tp->genParticles().empty() && (simInfo[
i].motherPdgId != 0)) {
394 if (
std::abs(simInfo[
i].motherPdgId) < 100 && (
std::abs(simInfo[
i].motherPdgId) != 15)) {
395 simInfo[
i].primaryClass = isGhost ?
398 simInfo[
i].flavour = 13;
399 simInfo[
i].extendedClass = isGhost ?
402 LogTrace(
"MuonSimClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << simInfo[
i].primaryClass;
403 }
else if (simInfo[
i].motherFlavour == 4 || simInfo[
i].motherFlavour == 5 || simInfo[
i].motherFlavour == 15) {
404 simInfo[
i].primaryClass = isGhost ?
407 simInfo[
i].flavour = simInfo[
i].motherFlavour;
408 if (simInfo[
i].motherFlavour == 15)
409 simInfo[
i].extendedClass = isGhost ?
412 else if (simInfo[
i].motherFlavour == 5)
413 simInfo[
i].extendedClass = isGhost ?
416 else if (simInfo[
i].heaviestMotherFlavour == 5)
417 simInfo[
i].extendedClass = isGhost ?
421 simInfo[
i].extendedClass = isGhost ?
424 LogTrace(
"MuonSimClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
426 simInfo[
i].primaryClass = isGhost ?
429 simInfo[
i].flavour = simInfo[
i].motherFlavour;
430 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
433 simInfo[
i].primaryClass = isGhost ?
436 simInfo[
i].flavour = simInfo[
i].motherFlavour;
437 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
442 if (simInfo[
i].motherPdgId == 0)
444 simInfo[
i].extendedClass = isGhost ?
447 else if (
std::abs(simInfo[
i].motherPdgId) < 100) {
448 if (simInfo[
i].motherFlavour == 15)
449 simInfo[
i].extendedClass = isGhost ?
453 simInfo[
i].extendedClass = isGhost ?
457 else if (simInfo[
i].motherFlavour == 5)
458 simInfo[
i].extendedClass = isGhost ?
461 else if (simInfo[
i].motherFlavour == 4)
463 if (simInfo[
i].heaviestMotherFlavour == 5)
464 simInfo[
i].extendedClass = isGhost ?
468 simInfo[
i].extendedClass = isGhost ?
472 else if (simInfo[
i].motherStatus != -1) {
473 int id =
std::abs(simInfo[
i].motherPdgId);
474 if (
id != 211 &&
id != 321 &&
id != 130 )
476 simInfo[
i].extendedClass = isGhost ?
481 simInfo[
i].extendedClass = isGhost ?
486 simInfo[
i].extendedClass = isGhost ?
491 simInfo[
i].extendedClass = isGhost ?
497 if (!tp->genParticles().empty() &&
std::abs(simInfo[
i].extendedClass) >= 5) {
498 if (genParticles.
id() != tp->genParticles().
id()) {
499 throw cms::Exception(
"Configuration") <<
"Product ID mismatch between the genParticle collection (" <<
500 genParticles_ <<
", id " << genParticles.
id() <<
") and the references in the TrackingParticles (id " <<
501 tp->genParticles().
id() <<
")\n";
503 muToPrimary[
i] = tp->genParticles()[0].
key();
506 int &indexPlus1 = tpToSecondaries[tp];
508 muToSecondary[
i] = indexPlus1 - 1;
511 LogTrace(
"MuonSimClassifier") <<
"\t Extended classification code = " << simInfo[
i].extendedClass;
527 fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
528 fillSec.
insert(muons, muToSecondary.begin(), muToSecondary.end());
529 fillPri.fill(); fillSec.
fill();
540 const std::vector<T> &
values,
545 unique_ptr<ValueMap<T> > valMap(
new ValueMap<T>());
557 if (flav <= 37 && flav != 21)
return flav;
559 int bflav = ((flav / 1000) % 10);
560 if (bflav != 0)
return bflav;
562 int mflav = ((flav / 100) % 10);
563 if (mflav != 0)
return mflav;
574 if (simMom.
isNonnull() && !simMom->genParticles().empty()) {
575 if (genParticles.
id() != simMom->genParticles().
id()) {
576 throw cms::Exception(
"Configuration") <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id " << genParticles.
id() <<
") and the references in the TrackingParticles (id " << simMom->genParticles().
id() <<
")\n";
578 out.back().addMother(simMom->genParticles()[0]);
const LorentzVector & p4() const
Four-momentum Lorentz vector. Note this is taken from the first SimTrack only.
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
bool isNonnull() const
Checks for non-null.
std::vector< TrackingParticle > TrackingParticleCollection
bool getByToken(EDGetToken token, Handle< PROD > &result) const
TrackingParticleRef getTpMother(TrackingParticleRef tp)
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
#define DEFINE_FWK_MODULE(type)
void produce(edm::Event &, const edm::EventSetup &) override
int pdgId() const
PDG ID.
reco::MuonTrackType trackType_
Track to use.
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
void insert(const H &h, I begin, I end)
int flavour(int pdgId) const
Returns the flavour given a pdg id code.
int convertAndPush(const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
key_type key() const
Accessor for product key.
void writeValueMap(edm::Event &iEvent, const edm::Handle< edm::View< reco::Muon > > &handle, const std::vector< T > &values, const std::string &label) const
Write a ValueMap<int> in the event.
value_type at(size_type idx) const
int status() const
Status word.
ProductID id() const
Accessor for product ID.
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
float charge() const
Electric charge. Note this is taken from the first SimTrack only.
edm::InputTag genParticles_
bool isGlobalMuon() const override
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &muons, MuonTrackType type, const edm::RefVector< TrackingParticleCollection > &tpColl) const
MuonSimClassifier(const edm::ParameterSet &)
Abs< T >::type abs(const T &t)
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
T const * product() const
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
void dumpFormatedInfo(const reco::MuonSimInfo &simInfo)
edm::InputTag associatorLabel_
The Associations.
Point vertex() const
Parent vertex position.
double decayRho_
Cylinder to use to decide if a decay is early or late.
void push_back(const RefToBase< T > &)
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Monte Carlo truth information used for tracking validation.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
bool linkToGenParticles_
Create a link to the generator level particles.
edm::Ref< TrackingParticleCollection > TrackingParticleRef
~MuonSimClassifier() override