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 hasMuonCut_(iConfig.existsAs<std::
string>(
"muonPreselection")),
128 muonCut_(hasMuonCut_ ? iConfig.getParameter<std::
string>(
"muonPreselection") :
""),
129 trackingParticlesToken_(
132 consumes<
reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::
InputTag>(
"associatorLabel"))),
133 decayRho_(iConfig.getParameter<double>(
"decayRho")),
134 decayAbsZ_(iConfig.getParameter<double>(
"decayAbsZ")),
135 linkToGenParticles_(iConfig.getParameter<bool>(
"linkToGenParticles")),
136 genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::
InputTag>(
"genParticles") : edm::
InputTag(
"NONE"))
140 if (trackType ==
"inner")
142 else if (trackType ==
"outer")
144 else if (trackType ==
"global")
146 else if (trackType ==
"segments")
148 else if (trackType ==
"glb_or_trk")
151 throw cms::Exception(
"Configuration") <<
"Track type '" << trackType <<
"' not supported.\n";
156 produces<edm::ValueMap<int> >();
157 produces<edm::ValueMap<int> >(
"ext");
158 produces<edm::ValueMap<int> >(
"flav");
159 produces<edm::ValueMap<int> >(
"hitsPdgId");
160 produces<edm::ValueMap<int> >(
"G4processType");
161 produces<edm::ValueMap<int> >(
"momPdgId");
162 produces<edm::ValueMap<int> >(
"momFlav");
163 produces<edm::ValueMap<int> >(
"momStatus");
164 produces<edm::ValueMap<int> >(
"gmomPdgId");
165 produces<edm::ValueMap<int> >(
"gmomFlav");
166 produces<edm::ValueMap<int> >(
"hmomFlav");
167 produces<edm::ValueMap<int> >(
"tpId");
168 produces<edm::ValueMap<int> >(
"tpEv");
169 produces<edm::ValueMap<int> >(
"tpBx");
170 produces<edm::ValueMap<float> >(
"signp");
171 produces<edm::ValueMap<float> >(
"pt");
172 produces<edm::ValueMap<float> >(
"eta");
173 produces<edm::ValueMap<float> >(
"phi");
174 produces<edm::ValueMap<float> >(
"prodRho");
175 produces<edm::ValueMap<float> >(
"prodZ");
176 produces<edm::ValueMap<float> >(
"momRho");
177 produces<edm::ValueMap<float> >(
"momZ");
178 produces<edm::ValueMap<float> >(
"tpAssoQuality");
180 produces<reco::GenParticleCollection>(
"secondaries");
181 produces<edm::Association<reco::GenParticleCollection> >(
"toPrimaries");
182 produces<edm::Association<reco::GenParticleCollection> >(
"toSecondaries");
206 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
208 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
213 for (
size_t i = 0,
n = muons->size();
i <
n; ++
i) {
220 for (
size_t i = 0,
n = muons->size();
i <
n; ++
i) {
228 for (
size_t i = 0,
n = trackingParticles->size();
i <
n; ++
i) {
238 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
239 edm::LogVerbatim(
"MuonMCClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
240 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
244 typedef reco::MuonToSimCollection::const_iterator r2s_it;
245 typedef reco::SimToMuonCollection::const_iterator s2r_it;
247 size_t nmu = muons->size();
248 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n There are " << nmu <<
" reco::Muons.";
250 std::vector<int> classif(nmu, 0), ext(nmu, 0);
251 std::vector<int> hitsPdgId(nmu, 0), G4processType(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
252 std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
253 std::vector<int> tpId(nmu, -1), tpBx(nmu, 999), tpEv(nmu, 999);
254 std::vector<float> signp(nmu, 0.0),
pt(nmu, 0.0),
eta(nmu, -99.),
phi(nmu, -99.);
255 std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
256 std::vector<float> tpAssoQuality(nmu, -1);
258 std::unique_ptr<reco::GenParticleCollection> secondaries;
259 std::map<TrackingParticleRef, int> tpToSecondaries;
260 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1);
262 secondaries = std::make_unique<reco::GenParticleCollection>();
265 for (
size_t i = 0;
i < nmu; ++
i) {
268 LogTrace(
"MuonMCClassifier") <<
"\n reco::Muon # " <<
i
269 <<
"didn't pass the selection. classified as -99 and skipped";
277 r2s_it
match = recSimColl.find(mu);
279 if (match != recSimColl.end()) {
281 tp = match->second.front().first;
283 tpAssoQuality[
i] = match->second.front().second;
284 s2r_it matchback = simRecColl.find(tp);
285 if (matchback != simRecColl.end()) {
286 muMatchBack = matchback->second.front().first;
288 edm::LogWarning(
"MuonMCClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back? *** \n";
292 r2s_it matchSta = UpdSTA_recSimColl.find(mu);
293 if (matchSta != UpdSTA_recSimColl.end()) {
294 tp = matchSta->second.front().first;
296 tpAssoQuality[
i] = matchSta->second.front().second;
297 s2r_it matchback = UpdSTA_simRecColl.find(tp);
298 if (matchback != UpdSTA_simRecColl.end()) {
299 muMatchBack = matchback->second.front().first;
302 <<
"\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
306 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t No matching TrackingParticle is found ";
310 bool isGhost = muMatchBack !=
mu;
312 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t *** This seems a Duplicate muon ! classif[i] will be < 0 ***";
315 tpBx[
i] = tp->eventId().bunchCrossing();
316 tpEv[
i] = tp->eventId().event();
318 hitsPdgId[
i] = tp->pdgId();
319 prodRho[
i] = tp->vertex().Rho();
320 prodZ[
i] = tp->vertex().Z();
323 const std::vector<SimVertex> &G4Vs = tp->parentVertex()->g4Vertices();
324 G4processType[
i] = G4Vs[0].processType();
326 signp[
i] = tp->charge() * tp->p();
333 if (!tp->genParticles().empty()) {
339 if (genMom->pdgId() != tp->pdgId()) {
340 momPdgId[
i] = genMom->pdgId();
341 momStatus[
i] = genMom->status();
342 momRho[
i] = genMom->vertex().Rho();
343 momZ[
i] = genMom->vz();
347 while (mMom->pdgId() == tp->pdgId()) {
350 if (mMom->numberOfMothers() > 0) {
351 mMom = mMom->motherRef();
353 LogTrace(
"MuonMCClassifier") <<
"\t\t backtracking mother " << jm <<
", pdgId = " << mMom->pdgId()
354 <<
", status= " << mMom->status();
357 momPdgId[
i] = genMom->pdgId();
358 momStatus[
i] = genMom->status();
359 momRho[
i] = genMom->vertex().Rho();
360 momZ[
i] = genMom->vz();
363 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
364 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
365 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " << phi[
i]
366 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
367 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
368 <<
"\n\t has GEN mother pdgId = " << momPdgId[
i] <<
" (status = " << momStatus[
i] <<
")";
373 gmomPdgId[
i] = genGMom->pdgId();
374 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t mother prod. vertex rho = " << momRho[
i]
375 <<
", z = " << momZ[
i] <<
", grand-mom pdgId = " << gmomPdgId[
i];
382 int flav =
flavour(nMom->pdgId());
383 if (hmomFlav[
i] < flav)
385 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
386 <<
", flavour = " << flav <<
", heaviest so far = " << hmomFlav[
i];
392 <<
"\t GenParticle with pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
393 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
394 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " << phi[
i]
395 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
396 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
397 <<
"\n\t has NO mother!";
403 momPdgId[
i] = simMom->pdgId();
404 momRho[
i] = simMom->vertex().Rho();
405 momZ[
i] = simMom->vertex().Z();
407 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
408 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
409 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " << phi[
i]
410 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
411 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
412 <<
"\n\t has SIM mother pdgId = " << momPdgId[
i] <<
" produced at rho = " << simMom->vertex().Rho()
413 <<
", z = " << simMom->vertex().Z();
415 if (!simMom->genParticles().empty()) {
416 momStatus[
i] = simMom->genParticles()[0]->status();
418 (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
421 gmomPdgId[
i] = genGMom->pdgId();
423 <<
"\t\t SIM mother is in GEN (status " << momStatus[
i] <<
"), grand-mom id = " << gmomPdgId[
i];
428 gmomPdgId[
i] = simGMom->pdgId();
429 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[
i];
433 <<
"\t Particle pdgId = " << hitsPdgId[
i] <<
", (Event,Bx) = "
434 <<
"(" << tpEv[
i] <<
"," << tpBx[
i] <<
")"
435 <<
"\n\t q*p = " << signp[
i] <<
", pT = " <<
pt[
i] <<
", eta = " <<
eta[
i] <<
", phi = " << phi[
i]
436 <<
"\n\t produced at vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i]
437 <<
", (GEANT4 process = " << G4processType[
i] <<
")"
438 <<
"\n\t has NO mother!";
442 gmomFlav[
i] =
flavour(gmomPdgId[i]);
445 if (
abs(tp->pdgId()) != 13) {
446 if (
abs(tp->pdgId()) == 11) {
447 classif[
i] = isGhost ? -11 : 11;
448 ext[
i] = isGhost ? -11 : 11;
449 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This is electron/positron. classif[i] = " << classif[
i];
451 classif[
i] = isGhost ? -1 : 1;
452 ext[
i] = isGhost ? -1 : 1;
453 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << classif[
i];
460 if (!tp->genParticles().empty() && (momPdgId[
i] != 0)) {
461 if (
abs(momPdgId[i]) < 100 && (
abs(momPdgId[i]) != 15)) {
462 classif[
i] = isGhost ? -4 : 4;
465 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << classif[
i];
466 }
else if (momFlav[i] == 4 || momFlav[i] == 5 || momFlav[i] == 15) {
467 classif[
i] = isGhost ? -3 : 3;
468 flav[
i] = momFlav[
i];
469 if (momFlav[i] == 15)
471 else if (momFlav[i] == 5)
473 else if (hmomFlav[i] == 5)
477 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[
i];
479 classif[
i] = isGhost ? -2 : 2;
480 flav[
i] = momFlav[
i];
481 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
484 classif[
i] = isGhost ? -2 : 2;
485 flav[
i] = momFlav[
i];
486 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
489 if (momPdgId[i] == 0)
491 else if (
abs(momPdgId[i]) < 100)
492 ext[
i] = (momFlav[
i] == 15 ? 9 : 10);
493 else if (momFlav[i] == 5)
495 else if (momFlav[i] == 4)
496 ext[
i] = (hmomFlav[
i] == 5 ? 7 : 6);
497 else if (momStatus[i] != -1) {
499 if (
id != 211 &&
id != 321 &&
id != 130 )
512 if (!tp->genParticles().empty() &&
std::abs(ext[i]) >= 5) {
513 if (genParticles.
id() != tp->genParticles().
id()) {
515 <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id "
516 << genParticles.
id() <<
") and the references in the TrackingParticles (id " << tp->genParticles().
id()
519 muToPrimary[
i] = tp->genParticles()[0].
key();
522 int &indexPlus1 = tpToSecondaries[
tp];
525 muToSecondary[
i] = indexPlus1 - 1;
528 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t Extended classification code = " << ext[
i];
539 writeValueMap(iEvent, muons, G4processType,
"G4processType");
554 writeValueMap(iEvent, muons, tpAssoQuality,
"tpAssoQuality");
560 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(
562 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(
565 fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
566 fillSec.
insert(muons, muToSecondary.begin(), muToSecondary.end());
574 template <
typename T>
577 const std::vector<T> &
values,
581 unique_ptr<ValueMap<T> > valMap(
new ValueMap<T>());
592 if (flav <= 37 && flav != 21)
595 int bflav = ((flav / 1000) % 10);
599 int mflav = ((flav / 100) % 10);
612 if (simMom.
isNonnull() && !simMom->genParticles().empty()) {
613 if (genParticles.
id() != simMom->genParticles().
id()) {
615 <<
"Product ID mismatch between the genParticle collection (" <<
genParticles_ <<
", id " << genParticles.
id()
616 <<
") and the references in the TrackingParticles (id " << simMom->genParticles().
id() <<
")\n";
618 out.back().addMother(simMom->genParticles()[0]);
620 return out.size() - 1;
edm::InputTag genParticles_
bool linkToGenParticles_
Create a link to the generator level particles.
const LorentzVector & p4() const
Four-momentum Lorentz vector. Note this is taken from the first SimTrack only.
Log< level::Info, true > LogVerbatim
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
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.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
#define DEFINE_FWK_MODULE(type)
int pdgId() const
PDG ID.
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
void insert(const H &h, I begin, I end)
const_iterator end() const
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 find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
int status() const
Status word.
ProductID id() const
Accessor for product ID.
reco::MuonTrackType trackType_
Track to use.
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
~MuonMCClassifier() override
float charge() const
Electric charge. Note this is taken from the first SimTrack only.
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)
TrackingParticleRef getTpMother(TrackingParticleRef tp)
MuonMCClassifier(const edm::ParameterSet &)
edm::InputTag associatorLabel_
The Associations.
tuple genp
produce generated paricles in acceptance #
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
T const * product() const
T getParameter(std::string const &) const
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.
edm::EDGetTokenT< reco::MuonToTrackingParticleAssociator > muAssocToken_
const_iterator begin() const
Point vertex() const
Parent vertex position.
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.
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
Log< level::Warning, false > LogWarning
int flavour(int pdgId) const
Returns the flavour given a pdg id code.
void produce(edm::Event &, const edm::EventSetup &) override
Analysis-level muon class.
bool isGlobalMuon() const override
edm::Ref< TrackingParticleCollection > TrackingParticleRef
edm::EDGetTokenT< TrackingParticleCollection > trackingParticlesToken_
The TrackingParticle objects.
StringCutObjectSelector< pat::Muon > muonCut_