101 template <
typename T>
104 const std::vector<T> &
values,
108 if (
tp.isNonnull() &&
tp->parentVertex().isNonnull() && !
tp->parentVertex()->sourceTracks().empty()) {
109 return tp->parentVertex()->sourceTracks()[0];
126 trackingParticlesToken_(
129 consumes<
reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<
edm::
InputTag>(
"associatorLabel"))),
130 decayRho_(iConfig.getParameter<double>(
"decayRho")),
131 decayAbsZ_(iConfig.getParameter<double>(
"decayAbsZ")),
132 linkToGenParticles_(iConfig.getParameter<
bool>(
"linkToGenParticles")),
133 genParticles_(linkToGenParticles_ ? iConfig.getParameter<
edm::
InputTag>(
"genParticles") :
edm::
InputTag())
153 produces<edm::ValueMap<reco::MuonSimInfo>>();
155 produces<reco::GenParticleCollection>(
"secondaries");
156 produces<edm::Association<reco::GenParticleCollection>>(
"toPrimaries");
157 produces<edm::Association<reco::GenParticleCollection>>(
"toSecondaries");
165 LogTrace(
"MuonSimClassifier") <<
"\t Particle pdgId = " << simInfo.
pdgId <<
", (Event,Bx) = " 166 <<
"(" << simInfo.
tpEvent <<
"," << simInfo.
tpBX <<
")" 167 <<
"\n\t q*p = " << simInfo.
charge * simInfo.
p4.P() <<
", pT = " << simInfo.
p4.pt()
168 <<
", eta = " << simInfo.
p4.eta() <<
", phi = " << simInfo.
p4.phi()
169 <<
"\n\t produced at vertex rho = " << simInfo.
vertex.Rho()
192 LogTrace(
"MuonSimClassifier") <<
"\n " 193 "***************************************************************** ";
195 LogTrace(
"MuonSimClassifier") <<
" ******************************************" 196 "*********************** \n";
199 for (
size_t i = 0,
n =
muons->size();
i <
n; ++
i) {
215 LogTrace(
"MuonSimClassifier") <<
"\n " 216 "***************************************************************** ";
217 LogTrace(
"MuonSimClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
218 LogTrace(
"MuonSimClassifier") <<
" ****************************************" 219 "************************* \n";
223 typedef reco::MuonToSimCollection::const_iterator r2s_it;
224 typedef reco::SimToMuonCollection::const_iterator s2r_it;
226 size_t nmu =
muons->size();
227 LogTrace(
"MuonSimClassifier") <<
"\n There are " << nmu <<
" reco::Muons.";
229 std::vector<reco::MuonSimInfo> simInfo;
231 std::unique_ptr<reco::GenParticleCollection> secondaries;
232 std::map<TrackingParticleRef, int> tpToSecondaries;
233 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu,
236 secondaries = std::make_unique<reco::GenParticleCollection>();
239 for (
size_t i = 0;
i < nmu; ++
i) {
241 LogTrace(
"MuonSimClassifier") <<
"\n reco::Muon # " <<
i;
247 if (
match != recSimColl.end()) {
250 tp =
match->second.front().first;
251 simInfo[
i].tpId =
tp.isNonnull() ?
tp.key() : -1;
252 simInfo[
i].tpAssoQuality =
match->second.front().second;
253 s2r_it matchback = simRecColl.find(
tp);
254 if (matchback != simRecColl.end()) {
255 muMatchBack = matchback->second.front().first;
257 LogTrace(
"MuonSimClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back? " 263 r2s_it matchSta = updSTA_recSimColl.find(
allMuons.at(
i));
264 if (matchSta != updSTA_recSimColl.end()) {
265 tp = matchSta->second.front().first;
266 simInfo[
i].tpId =
tp.isNonnull() ?
tp.key() : -1;
268 simInfo[
i].tpAssoQuality = matchSta->second.front().second;
269 s2r_it matchback = updSTA_simRecColl.find(
tp);
270 if (matchback != updSTA_simRecColl.end()) {
271 muMatchBack = matchback->second.front().first;
273 LogTrace(
"MuonSimClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back " 278 LogTrace(
"MuonSimClassifier") <<
"\t No matching TrackingParticle is found ";
282 if (
tp.isNonnull()) {
283 bool isGhost = muMatchBack !=
allMuons.at(
i);
285 LogTrace(
"MuonSimClassifier") <<
"\t *** This seems a Duplicate muon ! " 286 "classif[i] will be < 0 ***";
289 simInfo[
i].tpBX =
tp->eventId().bunchCrossing();
290 simInfo[
i].tpEvent =
tp->eventId().event();
292 simInfo[
i].pdgId =
tp->pdgId();
293 simInfo[
i].vertex =
tp->vertex();
296 const std::vector<SimVertex> &g4Vs =
tp->parentVertex()->g4Vertices();
297 simInfo[
i].g4processType = g4Vs[0].processType();
299 simInfo[
i].charge =
tp->charge();
300 simInfo[
i].p4 =
tp->p4();
304 if (!
tp->genParticles().empty()) {
310 if (genMom->pdgId() !=
tp->pdgId()) {
311 simInfo[
i].motherPdgId = genMom->pdgId();
312 simInfo[
i].motherStatus = genMom->status();
313 simInfo[
i].motherVertex = genMom->vertex();
318 while (mMom->pdgId() ==
tp->pdgId()) {
320 if (mMom->numberOfMothers() > 0) {
321 mMom = mMom->motherRef();
323 LogTrace(
"MuonSimClassifier") <<
"\t No Mother is found ";
327 LogTrace(
"MuonSimClassifier") <<
"\t\t backtracking mother " << jm <<
", pdgId = " << mMom->pdgId()
328 <<
", status= " << mMom->status();
331 simInfo[
i].motherPdgId = genMom->pdgId();
332 simInfo[
i].motherStatus = genMom->status();
333 simInfo[
i].motherVertex = genMom->vertex();
336 LogTrace(
"MuonSimClassifier") <<
"\t has GEN mother pdgId = " << simInfo[
i].motherPdgId
337 <<
" (status = " << simInfo[
i].motherStatus <<
")";
342 simInfo[
i].grandMotherPdgId = genGMom->pdgId();
344 <<
"\t\t mother prod. vertex rho = " << simInfo[
i].motherVertex.Rho()
345 <<
", z = " << simInfo[
i].motherVertex.Z() <<
", grand-mom pdgId = " << simInfo[
i].grandMotherPdgId;
352 int flav =
flavour(nMom->pdgId());
353 if (simInfo[
i].heaviestMotherFlavour < flav)
354 simInfo[
i].heaviestMotherFlavour = flav;
356 <<
"\t\t backtracking flavour: mom pdgId = " << nMom->pdgId() <<
", flavour = " << flav
357 <<
", heaviest so far = " << simInfo[
i].heaviestMotherFlavour;
361 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
366 simInfo[
i].motherPdgId = simMom->pdgId();
367 simInfo[
i].motherVertex = simMom->vertex();
369 LogTrace(
"MuonSimClassifier") <<
"\t has SIM mother pdgId = " << simInfo[
i].motherPdgId
370 <<
" produced at rho = " << simMom->vertex().Rho()
371 <<
", z = " << simMom->vertex().Z();
373 if (!simMom->genParticles().empty()) {
374 simInfo[
i].motherStatus = simMom->genParticles()[0]->status();
376 (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
379 simInfo[
i].grandMotherPdgId = genGMom->pdgId();
380 LogTrace(
"MuonSimClassifier") <<
"\t\t SIM mother is in GEN (status " << simInfo[
i].motherStatus
381 <<
"), grand-mom id = " << simInfo[
i].grandMotherPdgId;
383 simInfo[
i].motherStatus = -1;
386 simInfo[
i].grandMotherPdgId = simGMom->pdgId();
388 <<
"\t\t SIM mother is in SIM only, grand-mom id = " << simInfo[
i].grandMotherPdgId;
392 LogTrace(
"MuonSimClassifier") <<
"\t has NO mother!";
395 simInfo[
i].motherFlavour =
flavour(simInfo[
i].motherPdgId);
396 simInfo[
i].grandMotherFlavour =
flavour(simInfo[
i].grandMotherPdgId);
402 simInfo[
i].extendedClass =
404 LogTrace(
"MuonSimClassifier") <<
"\t This is electron/positron. classif[i] = " << simInfo[
i].primaryClass;
406 simInfo[
i].primaryClass =
410 LogTrace(
"MuonSimClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << simInfo[
i].primaryClass;
416 if (!
tp->genParticles().empty() && (simInfo[
i].motherPdgId != 0)) {
417 if (
std::abs(simInfo[
i].motherPdgId) < 100 && (
std::abs(simInfo[
i].motherPdgId) != 15)) {
418 simInfo[
i].primaryClass =
420 simInfo[
i].flavour = 13;
423 LogTrace(
"MuonSimClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << simInfo[
i].primaryClass;
424 }
else if (simInfo[
i].motherFlavour == 4 || simInfo[
i].motherFlavour == 5 || simInfo[
i].motherFlavour == 15) {
425 simInfo[
i].primaryClass =
427 simInfo[
i].flavour = simInfo[
i].motherFlavour;
428 if (simInfo[
i].motherFlavour == 15)
429 simInfo[
i].extendedClass =
431 else if (simInfo[
i].motherFlavour == 5)
432 simInfo[
i].extendedClass =
434 else if (simInfo[
i].heaviestMotherFlavour == 5)
435 simInfo[
i].extendedClass =
438 simInfo[
i].extendedClass =
440 LogTrace(
"MuonSimClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
442 simInfo[
i].primaryClass =
444 simInfo[
i].flavour = simInfo[
i].motherFlavour;
445 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
448 simInfo[
i].primaryClass =
450 simInfo[
i].flavour = simInfo[
i].motherFlavour;
451 LogTrace(
"MuonSimClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << simInfo[
i].primaryClass;
456 if (simInfo[
i].motherPdgId == 0)
460 else if (
std::abs(simInfo[
i].motherPdgId) < 100) {
461 if (simInfo[
i].motherFlavour == 15)
462 simInfo[
i].extendedClass =
467 }
else if (simInfo[
i].motherFlavour == 5)
468 simInfo[
i].extendedClass =
470 else if (simInfo[
i].motherFlavour == 4) {
471 if (simInfo[
i].heaviestMotherFlavour == 5)
472 simInfo[
i].extendedClass =
475 simInfo[
i].extendedClass =
477 }
else if (simInfo[
i].motherStatus != -1) {
478 int id =
std::abs(simInfo[
i].motherPdgId);
479 if (
id != 211 &&
id != 321 &&
id != 130 )
499 if (!
tp->genParticles().empty() &&
std::abs(simInfo[
i].extendedClass) >= 5) {
502 <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id " 503 <<
genParticles.id() <<
") and the references in the TrackingParticles (id " <<
tp->genParticles().id()
506 muToPrimary[
i] =
tp->genParticles()[0].key();
509 int &indexPlus1 = tpToSecondaries[
tp];
513 muToSecondary[
i] = indexPlus1 - 1;
516 LogTrace(
"MuonSimClassifier") <<
"\t Extended classification code = " << simInfo[
i].extendedClass;
529 std::unique_ptr<edm::Association<reco::GenParticleCollection>> outPri(
531 std::unique_ptr<edm::Association<reco::GenParticleCollection>> outSec(
534 fillPri.insert(
muons, muToPrimary.begin(), muToPrimary.end());
535 fillSec.
insert(
muons, muToSecondary.begin(), muToSecondary.end());
543 template <
typename T>
546 const std::vector<T> &
values,
561 if (flav <= 37 && flav != 21)
564 int bflav = ((flav / 1000) % 10);
568 int mflav = ((flav / 100) % 10);
581 if (simMom.
isNonnull() && !simMom->genParticles().empty()) {
585 <<
") and the references in the TrackingParticles (id " << simMom->genParticles().
id() <<
")\n";
587 out.back().addMother(simMom->genParticles()[0]);
589 return out.size() - 1;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
T getParameter(std::string const &) const
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &muons, MuonTrackType type, const edm::RefVector< TrackingParticleCollection > &tpColl) const
genp
produce generated paricles in acceptance #
ProductID id() const
Accessor for product ID.
TrackingParticleRef getTpMother(TrackingParticleRef tp)
edm::EDGetTokenT< edm::View< reco::Muon > > muonsToken_
The RECO objects.
void produce(edm::Event &, const edm::EventSetup &) override
reco::MuonTrackType trackType_
Track to use.
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
T const * product() const
void insert(const H &h, I begin, I end)
bool isNonnull() const
Checks for non-null.
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
edm::InputTag genParticles_
MuonSimClassifier(const edm::ParameterSet &)
Abs< T >::type abs(const T &t)
#define DEFINE_FWK_MODULE(type)
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
void dumpFormatedInfo(const reco::MuonSimInfo &simInfo)
edm::InputTag associatorLabel_
The Associations.
double decayRho_
Cylinder to use to decide if a decay is early or late.
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
int convertAndPush(const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles) const
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.
std::vector< TrackingParticle > TrackingParticleCollection
bool linkToGenParticles_
Create a link to the generator level particles.
edm::Ref< TrackingParticleCollection > TrackingParticleRef
~MuonSimClassifier() override
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.
int flavour(int pdgId) const
Returns the flavour given a pdg id code.