103 template <
typename T>
106 const std::vector<T> &
values,
110 if (
tp.isNonnull() &&
tp->parentVertex().isNonnull() && !
tp->parentVertex()->sourceTracks().empty()) {
111 return tp->parentVertex()->sourceTracks()[0];
128 hasMuonCut_(iConfig.existsAs<
std::
string>(
"muonPreselection")),
129 muonCut_(hasMuonCut_ ? iConfig.getParameter<
std::
string>(
"muonPreselection") :
""),
130 trackingParticlesToken_(
133 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"))
157 produces<edm::ValueMap<int> >();
158 produces<edm::ValueMap<int> >(
"ext");
159 produces<edm::ValueMap<int> >(
"flav");
160 produces<edm::ValueMap<int> >(
"hitsPdgId");
161 produces<edm::ValueMap<int> >(
"G4processType");
162 produces<edm::ValueMap<int> >(
"momPdgId");
163 produces<edm::ValueMap<int> >(
"momFlav");
164 produces<edm::ValueMap<int> >(
"momStatus");
165 produces<edm::ValueMap<int> >(
"gmomPdgId");
166 produces<edm::ValueMap<int> >(
"gmomFlav");
167 produces<edm::ValueMap<int> >(
"hmomFlav");
168 produces<edm::ValueMap<int> >(
"tpId");
169 produces<edm::ValueMap<int> >(
"tpEv");
170 produces<edm::ValueMap<int> >(
"tpBx");
171 produces<edm::ValueMap<float> >(
"signp");
172 produces<edm::ValueMap<float> >(
"pt");
173 produces<edm::ValueMap<float> >(
"eta");
174 produces<edm::ValueMap<float> >(
"phi");
175 produces<edm::ValueMap<float> >(
"prodRho");
176 produces<edm::ValueMap<float> >(
"prodZ");
177 produces<edm::ValueMap<float> >(
"momRho");
178 produces<edm::ValueMap<float> >(
"momZ");
179 produces<edm::ValueMap<float> >(
"tpAssoQuality");
181 produces<reco::GenParticleCollection>(
"secondaries");
182 produces<edm::Association<reco::GenParticleCollection> >(
"toPrimaries");
183 produces<edm::Association<reco::GenParticleCollection> >(
"toSecondaries");
207 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
209 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
214 for (
size_t i = 0,
n =
muons->size();
i <
n; ++
i) {
221 for (
size_t i = 0,
n =
muons->size();
i <
n; ++
i) {
239 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
240 edm::LogVerbatim(
"MuonMCClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
241 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
245 typedef reco::MuonToSimCollection::const_iterator r2s_it;
246 typedef reco::SimToMuonCollection::const_iterator s2r_it;
248 size_t nmu =
muons->size();
249 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n There are " << nmu <<
" reco::Muons.";
251 std::vector<int> classif(nmu, 0),
ext(nmu, 0);
252 std::vector<int> hitsPdgId(nmu, 0), G4processType(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
253 std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
254 std::vector<int> tpId(nmu, -1), tpBx(nmu, 999), tpEv(nmu, 999);
255 std::vector<float> signp(nmu, 0.0),
pt(nmu, 0.0),
eta(nmu, -99.),
phi(nmu, -99.);
256 std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
257 std::vector<float> tpAssoQuality(nmu, -1);
259 std::unique_ptr<reco::GenParticleCollection> secondaries;
260 std::map<TrackingParticleRef, int> tpToSecondaries;
261 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1);
263 secondaries = std::make_unique<reco::GenParticleCollection>();
266 for (
size_t i = 0;
i < nmu; ++
i) {
269 LogTrace(
"MuonMCClassifier") <<
"\n reco::Muon # " <<
i
270 <<
"didn't pass the selection. classified as -99 and skipped";
278 r2s_it
match = recSimColl.find(
mu);
280 if (
match != recSimColl.end()) {
282 tp =
match->second.front().first;
283 tpId[
i] =
tp.isNonnull() ?
tp.key() : -1;
284 tpAssoQuality[
i] =
match->second.front().second;
285 s2r_it matchback = simRecColl.find(
tp);
286 if (matchback != simRecColl.end()) {
287 muMatchBack = matchback->second.front().first;
289 edm::LogWarning(
"MuonMCClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back? *** \n";
293 r2s_it matchSta = UpdSTA_recSimColl.find(
mu);
294 if (matchSta != UpdSTA_recSimColl.end()) {
295 tp = matchSta->second.front().first;
296 tpId[
i] =
tp.isNonnull() ?
tp.key() : -1;
297 tpAssoQuality[
i] = matchSta->second.front().second;
298 s2r_it matchback = UpdSTA_simRecColl.find(
tp);
299 if (matchback != UpdSTA_simRecColl.end()) {
300 muMatchBack = matchback->second.front().first;
303 <<
"\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
307 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t No matching TrackingParticle is found ";
310 if (
tp.isNonnull()) {
311 bool isGhost = muMatchBack !=
mu;
313 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t *** This seems a Duplicate muon ! classif[i] will be < 0 ***";
316 tpBx[
i] =
tp->eventId().bunchCrossing();
317 tpEv[
i] =
tp->eventId().event();
319 hitsPdgId[
i] =
tp->pdgId();
320 prodRho[
i] =
tp->vertex().Rho();
321 prodZ[
i] =
tp->vertex().Z();
324 const std::vector<SimVertex> &G4Vs =
tp->parentVertex()->g4Vertices();
325 G4processType[
i] = G4Vs[0].processType();
327 signp[
i] =
tp->charge() *
tp->p();
334 if (!
tp->genParticles().empty()) {
340 if (genMom->pdgId() !=
tp->pdgId()) {
341 momPdgId[
i] = genMom->pdgId();
342 momStatus[
i] = genMom->status();
343 momRho[
i] = genMom->vertex().Rho();
344 momZ[
i] = genMom->vz();
348 while (mMom->pdgId() ==
tp->pdgId()) {
351 if (mMom->numberOfMothers() > 0) {
352 mMom = mMom->motherRef();
354 LogTrace(
"MuonMCClassifier") <<
"\t\t backtracking mother " << jm <<
", pdgId = " << mMom->pdgId()
355 <<
", status= " << mMom->status();
358 momPdgId[
i] = genMom->pdgId();
359 momStatus[
i] = genMom->status();
360 momRho[
i] = genMom->vertex().Rho();
361 momZ[
i] = genMom->vz();
364 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
365 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
366 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " <<
phi[
i]
367 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
368 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
369 <<
"\n\t has GEN mother pdgId = " << momPdgId[
i] <<
" (status = " << momStatus[
i] <<
")";
374 gmomPdgId[
i] = genGMom->pdgId();
375 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t mother prod. vertex rho = " << momRho[
i]
376 <<
", z = " << momZ[
i] <<
", grand-mom pdgId = " << gmomPdgId[
i];
383 int flav =
flavour(nMom->pdgId());
384 if (hmomFlav[
i] < flav)
386 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
387 <<
", flavour = " << flav <<
", heaviest so far = " << hmomFlav[
i];
393 <<
"\t GenParticle with pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
394 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
395 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " <<
phi[
i]
396 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
397 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
398 <<
"\n\t has NO mother!";
404 momPdgId[
i] = simMom->pdgId();
405 momRho[
i] = simMom->vertex().Rho();
406 momZ[
i] = simMom->vertex().Z();
408 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
409 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
410 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " <<
phi[
i]
411 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
412 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
413 <<
"\n\t has SIM mother pdgId = " << momPdgId[
i] <<
" produced at rho = " << simMom->vertex().Rho()
414 <<
", z = " << simMom->vertex().Z();
416 if (!simMom->genParticles().empty()) {
417 momStatus[
i] = simMom->genParticles()[0]->status();
419 (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
422 gmomPdgId[
i] = genGMom->pdgId();
424 <<
"\t\t SIM mother is in GEN (status " << momStatus[
i] <<
"), grand-mom id = " << gmomPdgId[
i];
429 gmomPdgId[
i] = simGMom->pdgId();
430 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[
i];
434 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
435 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
436 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " <<
phi[
i]
437 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
438 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
439 <<
"\n\t has NO mother!";
446 if (
abs(
tp->pdgId()) != 13) {
447 if (
abs(
tp->pdgId()) == 11) {
448 classif[
i] = isGhost ? -11 : 11;
449 ext[
i] = isGhost ? -11 : 11;
450 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This is electron/positron. classif[i] = " << classif[
i];
452 classif[
i] = isGhost ? -1 : 1;
453 ext[
i] = isGhost ? -1 : 1;
454 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << classif[
i];
461 if (!
tp->genParticles().empty() && (momPdgId[
i] != 0)) {
462 if (
abs(momPdgId[
i]) < 100 && (
abs(momPdgId[
i]) != 15)) {
463 classif[
i] = isGhost ? -4 : 4;
466 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << classif[
i];
467 }
else if (momFlav[
i] == 4 || momFlav[
i] == 5 || momFlav[
i] == 15) {
468 classif[
i] = isGhost ? -3 : 3;
469 flav[
i] = momFlav[
i];
470 if (momFlav[
i] == 15)
472 else if (momFlav[
i] == 5)
474 else if (hmomFlav[
i] == 5)
478 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[
i];
480 classif[
i] = isGhost ? -2 : 2;
481 flav[
i] = momFlav[
i];
482 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
485 classif[
i] = isGhost ? -2 : 2;
486 flav[
i] = momFlav[
i];
487 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
490 if (momPdgId[
i] == 0)
492 else if (
abs(momPdgId[
i]) < 100)
493 ext[
i] = (momFlav[
i] == 15 ? 9 : 10);
494 else if (momFlav[
i] == 5)
496 else if (momFlav[
i] == 4)
497 ext[
i] = (hmomFlav[
i] == 5 ? 7 : 6);
498 else if (momStatus[
i] != -1) {
500 if (
id != 211 &&
id != 321 &&
id != 130 )
516 <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id "
517 <<
genParticles.id() <<
") and the references in the TrackingParticles (id " <<
tp->genParticles().id()
520 muToPrimary[
i] =
tp->genParticles()[0].key();
523 int &indexPlus1 = tpToSecondaries[
tp];
526 muToSecondary[
i] = indexPlus1 - 1;
561 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(
563 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(
566 fillPri.insert(
muons, muToPrimary.begin(), muToPrimary.end());
567 fillSec.
insert(
muons, muToSecondary.begin(), muToSecondary.end());
575 template <
typename T>
578 const std::vector<T> &
values,
582 unique_ptr<ValueMap<T> > valMap(
new ValueMap<T>());
593 if (flav <= 37 && flav != 21)
596 int bflav = ((flav / 1000) % 10);
600 int mflav = ((flav / 100) % 10);
613 if (simMom.
isNonnull() && !simMom->genParticles().empty()) {
617 <<
") and the references in the TrackingParticles (id " << simMom->genParticles().
id() <<
")\n";
619 out.back().addMother(simMom->genParticles()[0]);
621 return out.size() - 1;