102 template <
typename T>
105 const std::vector<T> &
values,
109 if (
tp.isNonnull() &&
tp->parentVertex().isNonnull() && !
tp->parentVertex()->sourceTracks().empty()) {
110 return tp->parentVertex()->sourceTracks()[0];
127 trackingParticlesToken_(
130 consumes<
reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<
edm::
InputTag>(
"associatorLabel"))),
131 decayRho_(iConfig.getParameter<double>(
"decayRho")),
132 decayAbsZ_(iConfig.getParameter<double>(
"decayAbsZ")),
133 linkToGenParticles_(iConfig.getParameter<
bool>(
"linkToGenParticles")),
134 genParticles_(linkToGenParticles_ ? iConfig.getParameter<
edm::
InputTag>(
"genParticles") :
edm::
InputTag())
154 produces<edm::ValueMap<reco::MuonSimInfo>>();
156 produces<reco::GenParticleCollection>(
"secondaries");
157 produces<edm::Association<reco::GenParticleCollection>>(
"toPrimaries");
158 produces<edm::Association<reco::GenParticleCollection>>(
"toSecondaries");
166 LogTrace(
"MuonSimClassifier") <<
"\t Particle pdgId = " << simInfo.
pdgId <<
", (Event,Bx) = "
167 <<
"(" << simInfo.
tpEvent <<
"," << simInfo.
tpBX <<
")"
168 <<
"\n\t q*p = " << simInfo.
charge * simInfo.
p4.P() <<
", pT = " << simInfo.
p4.pt()
169 <<
", eta = " << simInfo.
p4.eta() <<
", phi = " << simInfo.
p4.phi()
170 <<
"\n\t produced at vertex rho = " << simInfo.
vertex.Rho()
193 LogTrace(
"MuonSimClassifier") <<
"\n "
194 "***************************************************************** ";
196 LogTrace(
"MuonSimClassifier") <<
" ******************************************"
197 "*********************** \n";
200 for (
size_t i = 0,
n =
muons->size();
i <
n; ++
i) {
216 LogTrace(
"MuonSimClassifier") <<
"\n "
217 "***************************************************************** ";
218 LogTrace(
"MuonSimClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
219 LogTrace(
"MuonSimClassifier") <<
" ****************************************"
220 "************************* \n";
224 typedef reco::MuonToSimCollection::const_iterator r2s_it;
225 typedef reco::SimToMuonCollection::const_iterator s2r_it;
227 size_t nmu =
muons->size();
228 LogTrace(
"MuonSimClassifier") <<
"\n There are " << nmu <<
" reco::Muons.";
230 std::vector<reco::MuonSimInfo> simInfo;
232 std::unique_ptr<reco::GenParticleCollection> secondaries;
233 std::map<TrackingParticleRef, int> tpToSecondaries;
234 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu,
237 secondaries = std::make_unique<reco::GenParticleCollection>();
240 for (
size_t i = 0;
i < nmu; ++
i) {
242 LogTrace(
"MuonSimClassifier") <<
"\n reco::Muon # " <<
i;
248 if (
match != recSimColl.end()) {
251 tp =
match->second.front().first;
252 simInfo[
i].tpId =
tp.isNonnull() ?
tp.key() : -1;
253 simInfo[
i].tpAssoQuality =
match->second.front().second;
254 s2r_it matchback = simRecColl.find(
tp);
255 if (matchback != simRecColl.end()) {
256 muMatchBack = matchback->second.front().first;
258 LogTrace(
"MuonSimClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back? "
264 r2s_it matchSta = updSTA_recSimColl.find(
allMuons.at(
i));
265 if (matchSta != updSTA_recSimColl.end()) {
266 tp = matchSta->second.front().first;
267 simInfo[
i].tpId =
tp.isNonnull() ?
tp.key() : -1;
269 simInfo[
i].tpAssoQuality = matchSta->second.front().second;
270 s2r_it matchback = updSTA_simRecColl.find(
tp);
271 if (matchback != updSTA_simRecColl.end()) {
272 muMatchBack = matchback->second.front().first;
274 LogTrace(
"MuonSimClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back "
279 LogTrace(
"MuonSimClassifier") <<
"\t No matching TrackingParticle is found ";
283 if (
tp.isNonnull()) {
284 bool isGhost = muMatchBack !=
allMuons.at(
i);
286 LogTrace(
"MuonSimClassifier") <<
"\t *** This seems a Duplicate muon ! "
287 "classif[i] will be < 0 ***";
290 simInfo[
i].tpBX =
tp->eventId().bunchCrossing();
291 simInfo[
i].tpEvent =
tp->eventId().event();
293 simInfo[
i].pdgId =
tp->pdgId();
294 simInfo[
i].vertex =
tp->vertex();
297 const std::vector<SimVertex> &g4Vs =
tp->parentVertex()->g4Vertices();
298 simInfo[
i].g4processType = g4Vs[0].processType();
300 simInfo[
i].charge =
tp->charge();
301 simInfo[
i].p4 =
tp->p4();
305 if (!
tp->genParticles().empty()) {
311 if (genMom->pdgId() !=
tp->pdgId()) {
312 simInfo[
i].motherPdgId = genMom->pdgId();
313 simInfo[
i].motherStatus = genMom->status();
314 simInfo[
i].motherVertex = genMom->vertex();
319 while (mMom->pdgId() ==
tp->pdgId()) {
321 if (mMom->numberOfMothers() > 0) {
322 mMom = mMom->motherRef();
324 LogTrace(
"MuonSimClassifier") <<
"\t No Mother is found ";
328 LogTrace(
"MuonSimClassifier") <<
"\t\t backtracking mother " << jm <<
", pdgId = " << mMom->pdgId()
329 <<
", status= " << mMom->status();
332 simInfo[
i].motherPdgId = genMom->pdgId();
333 simInfo[
i].motherStatus = genMom->status();
334 simInfo[
i].motherVertex = genMom->vertex();
337 LogTrace(
"MuonSimClassifier") <<
"\t has GEN mother pdgId = " << simInfo[
i].motherPdgId
338 <<
" (status = " << simInfo[
i].motherStatus <<
")";
343 simInfo[
i].grandMotherPdgId = genGMom->pdgId();
345 <<
"\t\t mother prod. vertex rho = " << simInfo[
i].motherVertex.Rho()
346 <<
", z = " << simInfo[
i].motherVertex.Z() <<
", grand-mom pdgId = " << simInfo[
i].grandMotherPdgId;
353 int flav =
flavour(nMom->pdgId());
354 if (simInfo[
i].heaviestMotherFlavour < flav)
355 simInfo[
i].heaviestMotherFlavour = flav;
357 <<
"\t\t backtracking flavour: mom pdgId = " << nMom->pdgId() <<
", flavour = " << flav
358 <<
", heaviest so far = " << simInfo[
i].heaviestMotherFlavour;
362 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
367 simInfo[
i].motherPdgId = simMom->pdgId();
368 simInfo[
i].motherVertex = simMom->vertex();
370 LogTrace(
"MuonSimClassifier") <<
"\t has SIM mother pdgId = " << simInfo[
i].motherPdgId
371 <<
" produced at rho = " << simMom->vertex().Rho()
372 <<
", z = " << simMom->vertex().Z();
374 if (!simMom->genParticles().empty()) {
375 simInfo[
i].motherStatus = simMom->genParticles()[0]->status();
377 (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
380 simInfo[
i].grandMotherPdgId = genGMom->pdgId();
381 LogTrace(
"MuonSimClassifier") <<
"\t\t SIM mother is in GEN (status " << simInfo[
i].motherStatus
382 <<
"), grand-mom id = " << simInfo[
i].grandMotherPdgId;
384 simInfo[
i].motherStatus = -1;
387 simInfo[
i].grandMotherPdgId = simGMom->pdgId();
389 <<
"\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[
i].grandMotherPdgId;
393 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
396 simInfo[
i].motherFlavour =
flavour(simInfo[
i].motherPdgId);
397 simInfo[
i].grandMotherFlavour =
flavour(simInfo[
i].grandMotherPdgId);
403 simInfo[
i].extendedClass =
405 LogTrace(
"MuonSimClassifier") <<
"\t This is electron/positron. classif[i] = " << simInfo[
i].primaryClass;
407 simInfo[
i].primaryClass =
411 LogTrace(
"MuonSimClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << simInfo[
i].primaryClass;
417 if (!
tp->genParticles().empty() && (simInfo[
i].motherPdgId != 0)) {
418 if (
std::abs(simInfo[
i].motherPdgId) < 100 && (
std::abs(simInfo[
i].motherPdgId) != 15)) {
419 simInfo[
i].primaryClass =
421 simInfo[
i].flavour = 13;
424 LogTrace(
"MuonSimClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << simInfo[
i].primaryClass;
425 }
else if (simInfo[
i].motherFlavour == 4 || simInfo[
i].motherFlavour == 5 || simInfo[
i].motherFlavour == 15) {
426 simInfo[
i].primaryClass =
428 simInfo[
i].flavour = simInfo[
i].motherFlavour;
429 if (simInfo[
i].motherFlavour == 15)
430 simInfo[
i].extendedClass =
432 else if (simInfo[
i].motherFlavour == 5)
433 simInfo[
i].extendedClass =
435 else if (simInfo[
i].heaviestMotherFlavour == 5)
436 simInfo[
i].extendedClass =
439 simInfo[
i].extendedClass =
441 LogTrace(
"MuonSimClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
443 simInfo[
i].primaryClass =
445 simInfo[
i].flavour = simInfo[
i].motherFlavour;
446 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
449 simInfo[
i].primaryClass =
451 simInfo[
i].flavour = simInfo[
i].motherFlavour;
452 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
457 if (simInfo[
i].motherPdgId == 0)
461 else if (
std::abs(simInfo[
i].motherPdgId) < 100) {
462 if (simInfo[
i].motherFlavour == 15)
463 simInfo[
i].extendedClass =
468 }
else if (simInfo[
i].motherFlavour == 5)
469 simInfo[
i].extendedClass =
471 else if (simInfo[
i].motherFlavour == 4) {
472 if (simInfo[
i].heaviestMotherFlavour == 5)
473 simInfo[
i].extendedClass =
476 simInfo[
i].extendedClass =
478 }
else if (simInfo[
i].motherStatus != -1) {
479 int id =
std::abs(simInfo[
i].motherPdgId);
480 if (
id != 211 &&
id != 321 &&
id != 130 )
500 if (!
tp->genParticles().empty() &&
std::abs(simInfo[
i].extendedClass) >= 5) {
503 <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id "
504 <<
genParticles.id() <<
") and the references in the TrackingParticles (id " <<
tp->genParticles().id()
507 muToPrimary[
i] =
tp->genParticles()[0].key();
510 int &indexPlus1 = tpToSecondaries[
tp];
514 muToSecondary[
i] = indexPlus1 - 1;
517 LogTrace(
"MuonSimClassifier") <<
"\t Extended classification code = " << simInfo[
i].extendedClass;
530 std::unique_ptr<edm::Association<reco::GenParticleCollection>> outPri(
532 std::unique_ptr<edm::Association<reco::GenParticleCollection>> outSec(
535 fillPri.insert(
muons, muToPrimary.begin(), muToPrimary.end());
536 fillSec.
insert(
muons, muToSecondary.begin(), muToSecondary.end());
544 template <
typename T>
547 const std::vector<T> &
values,
562 if (flav <= 37 && flav != 21)
565 int bflav = ((flav / 1000) % 10);
569 int mflav = ((flav / 100) % 10);
582 if (simMom.
isNonnull() && !simMom->genParticles().empty()) {
586 <<
") and the references in the TrackingParticles (id " << simMom->genParticles().
id() <<
")\n";
588 out.back().addMother(simMom->genParticles()[0]);
590 return out.size() - 1;