File indexing completed on 2024-09-07 04:37:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include <memory>
0036 #include <set>
0037
0038
0039 #include "FWCore/Framework/interface/Frameworkfwd.h"
0040 #include "FWCore/Framework/interface/stream/EDProducer.h"
0041
0042 #include "FWCore/Framework/interface/Event.h"
0043 #include "FWCore/Framework/interface/MakerMacros.h"
0044 #include "FWCore/Framework/interface/EventSetup.h"
0045 #include "FWCore/Framework/interface/ESHandle.h"
0046
0047 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0048
0049 #include "DataFormats/Common/interface/View.h"
0050 #include "DataFormats/Common/interface/ValueMap.h"
0051 #include "DataFormats/Common/interface/Association.h"
0052
0053 #include "DataFormats/MuonReco/interface/Muon.h"
0054 #include "DataFormats/PatCandidates/interface/Muon.h"
0055 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0056 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0057
0058 #include "SimDataFormats/Associations/interface/MuonToTrackingParticleAssociator.h"
0059 #include <SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h>
0060
0061 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0062
0063
0064
0065 class MuonMCClassifier : public edm::stream::EDProducer<> {
0066 public:
0067 explicit MuonMCClassifier(const edm::ParameterSet &);
0068 ~MuonMCClassifier() override;
0069
0070 private:
0071 void produce(edm::Event &, const edm::EventSetup &) override;
0072
0073 edm::EDGetTokenT<edm::View<reco::Muon> > muonsToken_;
0074
0075
0076
0077 bool hasMuonCut_;
0078 StringCutObjectSelector<pat::Muon> muonCut_;
0079
0080
0081 reco::MuonTrackType trackType_;
0082
0083
0084 edm::EDGetTokenT<TrackingParticleCollection> trackingParticlesToken_;
0085
0086
0087 edm::InputTag associatorLabel_;
0088 edm::EDGetTokenT<reco::MuonToTrackingParticleAssociator> muAssocToken_;
0089
0090
0091 double decayRho_, decayAbsZ_;
0092
0093
0094 bool linkToGenParticles_;
0095 edm::InputTag genParticles_;
0096 edm::EDGetTokenT<reco::GenParticleCollection> genParticlesToken_;
0097
0098
0099 int flavour(int pdgId) const;
0100
0101
0102 template <typename T>
0103 void writeValueMap(edm::Event &iEvent,
0104 const edm::Handle<edm::View<reco::Muon> > &handle,
0105 const std::vector<T> &values,
0106 const std::string &label) const;
0107
0108 TrackingParticleRef getTpMother(TrackingParticleRef tp) {
0109 if (tp.isNonnull() && tp->parentVertex().isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
0110 return tp->parentVertex()->sourceTracks()[0];
0111 } else {
0112 return TrackingParticleRef();
0113 }
0114 }
0115
0116
0117
0118
0119 int convertAndPush(const TrackingParticle &tp,
0120 reco::GenParticleCollection &out,
0121 const TrackingParticleRef &momRef,
0122 const edm::Handle<reco::GenParticleCollection> &genParticles) const;
0123 };
0124
0125 MuonMCClassifier::MuonMCClassifier(const edm::ParameterSet &iConfig)
0126 : muonsToken_(consumes<edm::View<reco::Muon> >(iConfig.getParameter<edm::InputTag>("muons"))),
0127 hasMuonCut_(iConfig.existsAs<std::string>("muonPreselection")),
0128 muonCut_(hasMuonCut_ ? iConfig.getParameter<std::string>("muonPreselection") : ""),
0129 trackingParticlesToken_(
0130 consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
0131 muAssocToken_(
0132 consumes<reco::MuonToTrackingParticleAssociator>(iConfig.getParameter<edm::InputTag>("associatorLabel"))),
0133 decayRho_(iConfig.getParameter<double>("decayRho")),
0134 decayAbsZ_(iConfig.getParameter<double>("decayAbsZ")),
0135 linkToGenParticles_(iConfig.getParameter<bool>("linkToGenParticles")),
0136 genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::InputTag>("genParticles") : edm::InputTag("NONE"))
0137
0138 {
0139 std::string trackType = iConfig.getParameter<std::string>("trackType");
0140 if (trackType == "inner")
0141 trackType_ = reco::InnerTk;
0142 else if (trackType == "outer")
0143 trackType_ = reco::OuterTk;
0144 else if (trackType == "global")
0145 trackType_ = reco::GlobalTk;
0146 else if (trackType == "segments")
0147 trackType_ = reco::Segments;
0148 else if (trackType == "glb_or_trk")
0149 trackType_ = reco::GlbOrTrk;
0150 else
0151 throw cms::Exception("Configuration") << "Track type '" << trackType << "' not supported.\n";
0152 if (linkToGenParticles_) {
0153 genParticlesToken_ = consumes<reco::GenParticleCollection>(genParticles_);
0154 }
0155
0156 produces<edm::ValueMap<int> >();
0157 produces<edm::ValueMap<int> >("ext");
0158 produces<edm::ValueMap<int> >("flav");
0159 produces<edm::ValueMap<int> >("hitsPdgId");
0160 produces<edm::ValueMap<int> >("G4processType");
0161 produces<edm::ValueMap<int> >("momPdgId");
0162 produces<edm::ValueMap<int> >("momFlav");
0163 produces<edm::ValueMap<int> >("momStatus");
0164 produces<edm::ValueMap<int> >("gmomPdgId");
0165 produces<edm::ValueMap<int> >("gmomFlav");
0166 produces<edm::ValueMap<int> >("hmomFlav");
0167 produces<edm::ValueMap<int> >("tpId");
0168 produces<edm::ValueMap<int> >("tpEv");
0169 produces<edm::ValueMap<int> >("tpBx");
0170 produces<edm::ValueMap<float> >("signp");
0171 produces<edm::ValueMap<float> >("pt");
0172 produces<edm::ValueMap<float> >("eta");
0173 produces<edm::ValueMap<float> >("phi");
0174 produces<edm::ValueMap<float> >("prodRho");
0175 produces<edm::ValueMap<float> >("prodZ");
0176 produces<edm::ValueMap<float> >("momRho");
0177 produces<edm::ValueMap<float> >("momZ");
0178 produces<edm::ValueMap<float> >("tpAssoQuality");
0179 if (linkToGenParticles_) {
0180 produces<reco::GenParticleCollection>("secondaries");
0181 produces<edm::Association<reco::GenParticleCollection> >("toPrimaries");
0182 produces<edm::Association<reco::GenParticleCollection> >("toSecondaries");
0183 }
0184 }
0185
0186 MuonMCClassifier::~MuonMCClassifier() {}
0187
0188 void MuonMCClassifier::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0189 edm::Handle<edm::View<reco::Muon> > muons;
0190 iEvent.getByToken(muonsToken_, muons);
0191
0192 edm::Handle<TrackingParticleCollection> trackingParticles;
0193 iEvent.getByToken(trackingParticlesToken_, trackingParticles);
0194
0195 edm::Handle<reco::GenParticleCollection> genParticles;
0196 if (linkToGenParticles_) {
0197 iEvent.getByToken(genParticlesToken_, genParticles);
0198 }
0199
0200 edm::Handle<reco::MuonToTrackingParticleAssociator> associatorBase;
0201 iEvent.getByToken(muAssocToken_, associatorBase);
0202 const reco::MuonToTrackingParticleAssociator *assoByHits = associatorBase.product();
0203
0204 reco::MuonToSimCollection recSimColl;
0205 reco::SimToMuonCollection simRecColl;
0206 edm::LogVerbatim("MuonMCClassifier") << "\n ***************************************************************** ";
0207 edm::LogVerbatim("MuonMCClassifier") << " RECO MUON association, type: " << trackType_;
0208 edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
0209
0210 edm::RefToBaseVector<reco::Muon> selMuons;
0211 if (!hasMuonCut_) {
0212
0213 for (size_t i = 0, n = muons->size(); i < n; ++i) {
0214 edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
0215 selMuons.push_back(rmu);
0216 }
0217 } else {
0218
0219
0220 for (size_t i = 0, n = muons->size(); i < n; ++i) {
0221 edm::RefToBase<reco::Muon> rmu = muons->refAt(i);
0222 if (muonCut_(pat::Muon(rmu)))
0223 selMuons.push_back(rmu);
0224 }
0225 }
0226
0227 edm::RefVector<TrackingParticleCollection> allTPs;
0228 for (size_t i = 0, n = trackingParticles->size(); i < n; ++i) {
0229 allTPs.push_back(TrackingParticleRef(trackingParticles, i));
0230 }
0231
0232 assoByHits->associateMuons(recSimColl, simRecColl, selMuons, trackType_, allTPs);
0233
0234
0235 reco::MuonToSimCollection UpdSTA_recSimColl;
0236 reco::SimToMuonCollection UpdSTA_simRecColl;
0237 if (trackType_ == reco::GlobalTk) {
0238 edm::LogVerbatim("MuonMCClassifier") << "\n ***************************************************************** ";
0239 edm::LogVerbatim("MuonMCClassifier") << " STANDALONE (UpdAtVtx) MUON association ";
0240 edm::LogVerbatim("MuonMCClassifier") << " ***************************************************************** \n";
0241 assoByHits->associateMuons(UpdSTA_recSimColl, UpdSTA_simRecColl, selMuons, reco::OuterTk, allTPs);
0242 }
0243
0244 typedef reco::MuonToSimCollection::const_iterator r2s_it;
0245 typedef reco::SimToMuonCollection::const_iterator s2r_it;
0246
0247 size_t nmu = muons->size();
0248 edm::LogVerbatim("MuonMCClassifier") << "\n There are " << nmu << " reco::Muons.";
0249
0250 std::vector<int> classif(nmu, 0), ext(nmu, 0);
0251 std::vector<int> hitsPdgId(nmu, 0), G4processType(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
0252 std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
0253 std::vector<int> tpId(nmu, -1), tpBx(nmu, 999), tpEv(nmu, 999);
0254 std::vector<float> signp(nmu, 0.0), pt(nmu, 0.0), eta(nmu, -99.), phi(nmu, -99.);
0255 std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
0256 std::vector<float> tpAssoQuality(nmu, -1);
0257
0258 std::unique_ptr<reco::GenParticleCollection> secondaries;
0259 std::map<TrackingParticleRef, int> tpToSecondaries;
0260 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1);
0261 if (linkToGenParticles_)
0262 secondaries = std::make_unique<reco::GenParticleCollection>();
0263
0264
0265 for (size_t i = 0; i < nmu; ++i) {
0266 edm::RefToBase<reco::Muon> mu = muons->refAt(i);
0267 if (hasMuonCut_ && (std::find(selMuons.begin(), selMuons.end(), mu) == selMuons.end())) {
0268 LogTrace("MuonMCClassifier") << "\n reco::Muon # " << i
0269 << "didn't pass the selection. classified as -99 and skipped";
0270 classif[i] = -99;
0271 continue;
0272 } else
0273 edm::LogVerbatim("MuonMCClassifier") << "\n reco::Muon # " << i;
0274
0275 TrackingParticleRef tp;
0276 edm::RefToBase<reco::Muon> muMatchBack;
0277 r2s_it match = recSimColl.find(mu);
0278 s2r_it matchback;
0279 if (match != recSimColl.end()) {
0280
0281 tp = match->second.front().first;
0282 tpId[i] = tp.isNonnull() ? tp.key() : -1;
0283 tpAssoQuality[i] = match->second.front().second;
0284 s2r_it matchback = simRecColl.find(tp);
0285 if (matchback != simRecColl.end()) {
0286 muMatchBack = matchback->second.front().first;
0287 } else {
0288 edm::LogWarning("MuonMCClassifier") << "\n***WARNING: This I do NOT understand: why no match back? *** \n";
0289 }
0290 } else if ((trackType_ == reco::GlobalTk) && mu->isGlobalMuon()) {
0291
0292 r2s_it matchSta = UpdSTA_recSimColl.find(mu);
0293 if (matchSta != UpdSTA_recSimColl.end()) {
0294 tp = matchSta->second.front().first;
0295 tpId[i] = tp.isNonnull() ? tp.key() : -1;
0296 tpAssoQuality[i] = matchSta->second.front().second;
0297 s2r_it matchback = UpdSTA_simRecColl.find(tp);
0298 if (matchback != UpdSTA_simRecColl.end()) {
0299 muMatchBack = matchback->second.front().first;
0300 } else {
0301 edm::LogWarning("MuonMCClassifier")
0302 << "\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
0303 }
0304 }
0305 } else {
0306 edm::LogVerbatim("MuonMCClassifier") << "\t No matching TrackingParticle is found ";
0307 }
0308
0309 if (tp.isNonnull()) {
0310 bool isGhost = muMatchBack != mu;
0311 if (isGhost)
0312 edm::LogVerbatim("MuonMCClassifier") << "\t *** This seems a Duplicate muon ! classif[i] will be < 0 ***";
0313
0314
0315 tpBx[i] = tp->eventId().bunchCrossing();
0316 tpEv[i] = tp->eventId().event();
0317
0318 hitsPdgId[i] = tp->pdgId();
0319 prodRho[i] = tp->vertex().Rho();
0320 prodZ[i] = tp->vertex().Z();
0321
0322
0323 const std::vector<SimVertex> &G4Vs = tp->parentVertex()->g4Vertices();
0324 G4processType[i] = G4Vs[0].processType();
0325
0326 signp[i] = tp->charge() * tp->p();
0327 pt[i] = tp->pt();
0328 eta[i] = tp->eta();
0329 phi[i] = tp->phi();
0330
0331
0332
0333 if (!tp->genParticles().empty()) {
0334 reco::GenParticleRef genp = tp->genParticles()[0];
0335 reco::GenParticleRef genMom = genp->numberOfMothers() > 0 ? genp->motherRef() : reco::GenParticleRef();
0336 reco::GenParticleRef mMom = genMom;
0337
0338 if (genMom.isNonnull()) {
0339 if (genMom->pdgId() != tp->pdgId()) {
0340 momPdgId[i] = genMom->pdgId();
0341 momStatus[i] = genMom->status();
0342 momRho[i] = genMom->vertex().Rho();
0343 momZ[i] = genMom->vz();
0344 } else {
0345
0346 int jm = 0;
0347 while (mMom->pdgId() == tp->pdgId()) {
0348 jm++;
0349
0350 if (mMom->numberOfMothers() > 0) {
0351 mMom = mMom->motherRef();
0352 }
0353 LogTrace("MuonMCClassifier") << "\t\t backtracking mother " << jm << ", pdgId = " << mMom->pdgId()
0354 << ", status= " << mMom->status();
0355 }
0356 genMom = mMom;
0357 momPdgId[i] = genMom->pdgId();
0358 momStatus[i] = genMom->status();
0359 momRho[i] = genMom->vertex().Rho();
0360 momZ[i] = genMom->vz();
0361 }
0362 edm::LogVerbatim("MuonMCClassifier")
0363 << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
0364 << "(" << tpEv[i] << "," << tpBx[i] << ")"
0365 << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
0366 << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
0367 << ", (GEANT4 process = " << G4processType[i] << ")"
0368 << "\n\t has GEN mother pdgId = " << momPdgId[i] << " (status = " << momStatus[i] << ")";
0369
0370 reco::GenParticleRef genGMom = genMom->numberOfMothers() > 0 ? genMom->motherRef() : reco::GenParticleRef();
0371
0372 if (genGMom.isNonnull()) {
0373 gmomPdgId[i] = genGMom->pdgId();
0374 edm::LogVerbatim("MuonMCClassifier") << "\t\t mother prod. vertex rho = " << momRho[i]
0375 << ", z = " << momZ[i] << ", grand-mom pdgId = " << gmomPdgId[i];
0376 }
0377
0378 for (reco::GenParticleRef nMom = genMom;
0379 nMom.isNonnull() &&
0380 std::abs(nMom->pdgId()) >= 100;
0381 nMom = nMom->numberOfMothers() > 0 ? nMom->motherRef() : reco::GenParticleRef()) {
0382 int flav = flavour(nMom->pdgId());
0383 if (hmomFlav[i] < flav)
0384 hmomFlav[i] = flav;
0385 edm::LogVerbatim("MuonMCClassifier") << "\t\t backtracking flavour: mom pdgId = " << nMom->pdgId()
0386 << ", flavour = " << flav << ", heaviest so far = " << hmomFlav[i];
0387 }
0388 }
0389
0390 else {
0391 edm::LogWarning("MuonMCClassifier")
0392 << "\t GenParticle with pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
0393 << "(" << tpEv[i] << "," << tpBx[i] << ")"
0394 << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
0395 << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
0396 << ", (GEANT4 process = " << G4processType[i] << ")"
0397 << "\n\t has NO mother!";
0398 }
0399
0400 } else {
0401 TrackingParticleRef simMom = getTpMother(tp);
0402 if (simMom.isNonnull()) {
0403 momPdgId[i] = simMom->pdgId();
0404 momRho[i] = simMom->vertex().Rho();
0405 momZ[i] = simMom->vertex().Z();
0406 edm::LogVerbatim("MuonMCClassifier")
0407 << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
0408 << "(" << tpEv[i] << "," << tpBx[i] << ")"
0409 << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
0410 << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
0411 << ", (GEANT4 process = " << G4processType[i] << ")"
0412 << "\n\t has SIM mother pdgId = " << momPdgId[i] << " produced at rho = " << simMom->vertex().Rho()
0413 << ", z = " << simMom->vertex().Z();
0414
0415 if (!simMom->genParticles().empty()) {
0416 momStatus[i] = simMom->genParticles()[0]->status();
0417 reco::GenParticleRef genGMom =
0418 (simMom->genParticles()[0]->numberOfMothers() > 0 ? simMom->genParticles()[0]->motherRef()
0419 : reco::GenParticleRef());
0420 if (genGMom.isNonnull())
0421 gmomPdgId[i] = genGMom->pdgId();
0422 edm::LogVerbatim("MuonMCClassifier")
0423 << "\t\t SIM mother is in GEN (status " << momStatus[i] << "), grand-mom id = " << gmomPdgId[i];
0424 } else {
0425 momStatus[i] = -1;
0426 TrackingParticleRef simGMom = getTpMother(simMom);
0427 if (simGMom.isNonnull())
0428 gmomPdgId[i] = simGMom->pdgId();
0429 edm::LogVerbatim("MuonMCClassifier") << "\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[i];
0430 }
0431 } else {
0432 edm::LogVerbatim("MuonMCClassifier")
0433 << "\t Particle pdgId = " << hitsPdgId[i] << ", (Event,Bx) = "
0434 << "(" << tpEv[i] << "," << tpBx[i] << ")"
0435 << "\n\t q*p = " << signp[i] << ", pT = " << pt[i] << ", eta = " << eta[i] << ", phi = " << phi[i]
0436 << "\n\t produced at vertex rho = " << prodRho[i] << ", z = " << prodZ[i]
0437 << ", (GEANT4 process = " << G4processType[i] << ")"
0438 << "\n\t has NO mother!";
0439 }
0440 }
0441 momFlav[i] = flavour(momPdgId[i]);
0442 gmomFlav[i] = flavour(gmomPdgId[i]);
0443
0444
0445 if (abs(tp->pdgId()) != 13) {
0446 if (abs(tp->pdgId()) == 11) {
0447 classif[i] = isGhost ? -11 : 11;
0448 ext[i] = isGhost ? -11 : 11;
0449 edm::LogVerbatim("MuonMCClassifier") << "\t This is electron/positron. classif[i] = " << classif[i];
0450 } else {
0451 classif[i] = isGhost ? -1 : 1;
0452 ext[i] = isGhost ? -1 : 1;
0453 edm::LogVerbatim("MuonMCClassifier") << "\t This is not a muon. Sorry. classif[i] = " << classif[i];
0454 }
0455
0456 continue;
0457 }
0458
0459
0460 if (!tp->genParticles().empty() && (momPdgId[i] != 0)) {
0461 if (abs(momPdgId[i]) < 100 && (abs(momPdgId[i]) != 15)) {
0462 classif[i] = isGhost ? -4 : 4;
0463 flav[i] = 13;
0464 ext[i] = 10;
0465 edm::LogVerbatim("MuonMCClassifier") << "\t This seems PRIMARY MUON ! classif[i] = " << classif[i];
0466 } else if (momFlav[i] == 4 || momFlav[i] == 5 || momFlav[i] == 15) {
0467 classif[i] = isGhost ? -3 : 3;
0468 flav[i] = momFlav[i];
0469 if (momFlav[i] == 15)
0470 ext[i] = 9;
0471 else if (momFlav[i] == 5)
0472 ext[i] = 8;
0473 else if (hmomFlav[i] == 5)
0474 ext[i] = 7;
0475 else
0476 ext[i] = 6;
0477 edm::LogVerbatim("MuonMCClassifier") << "\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[i];
0478 } else {
0479 classif[i] = isGhost ? -2 : 2;
0480 flav[i] = momFlav[i];
0481 edm::LogVerbatim("MuonMCClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
0482 }
0483 } else {
0484 classif[i] = isGhost ? -2 : 2;
0485 flav[i] = momFlav[i];
0486 edm::LogVerbatim("MuonMCClassifier") << "\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[i];
0487 }
0488
0489 if (momPdgId[i] == 0)
0490 ext[i] = 2;
0491 else if (abs(momPdgId[i]) < 100)
0492 ext[i] = (momFlav[i] == 15 ? 9 : 10);
0493 else if (momFlav[i] == 5)
0494 ext[i] = 8;
0495 else if (momFlav[i] == 4)
0496 ext[i] = (hmomFlav[i] == 5 ? 7 : 6);
0497 else if (momStatus[i] != -1) {
0498 int id = std::abs(momPdgId[i]);
0499 if (id != 211 && id != 321 && id != 130 )
0500 ext[i] = 5;
0501 else if (prodRho[i] < decayRho_ && std::abs(prodZ[i]) < decayAbsZ_)
0502 ext[i] = 4;
0503 else
0504 ext[i] = 3;
0505 } else
0506 ext[i] = 2;
0507 if (isGhost)
0508 ext[i] = -ext[i];
0509
0510 if (linkToGenParticles_ && std::abs(ext[i]) >= 2) {
0511
0512 if (!tp->genParticles().empty() && std::abs(ext[i]) >= 5) {
0513 if (genParticles.id() != tp->genParticles().id()) {
0514 throw cms::Exception("Configuration")
0515 << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id "
0516 << genParticles.id() << ") and the references in the TrackingParticles (id " << tp->genParticles().id()
0517 << ")\n";
0518 }
0519 muToPrimary[i] = tp->genParticles()[0].key();
0520 } else {
0521
0522 int &indexPlus1 = tpToSecondaries[tp];
0523 if (indexPlus1 == 0)
0524 indexPlus1 = convertAndPush(*tp, *secondaries, getTpMother(tp), genParticles) + 1;
0525 muToSecondary[i] = indexPlus1 - 1;
0526 }
0527 }
0528 edm::LogVerbatim("MuonMCClassifier") << "\t Extended classification code = " << ext[i];
0529 }
0530 }
0531
0532 writeValueMap(iEvent, muons, classif, "");
0533 writeValueMap(iEvent, muons, ext, "ext");
0534 writeValueMap(iEvent, muons, flav, "flav");
0535 writeValueMap(iEvent, muons, tpId, "tpId");
0536 writeValueMap(iEvent, muons, tpBx, "tpBx");
0537 writeValueMap(iEvent, muons, tpEv, "tpEv");
0538 writeValueMap(iEvent, muons, hitsPdgId, "hitsPdgId");
0539 writeValueMap(iEvent, muons, G4processType, "G4processType");
0540 writeValueMap(iEvent, muons, momPdgId, "momPdgId");
0541 writeValueMap(iEvent, muons, momStatus, "momStatus");
0542 writeValueMap(iEvent, muons, momFlav, "momFlav");
0543 writeValueMap(iEvent, muons, gmomPdgId, "gmomPdgId");
0544 writeValueMap(iEvent, muons, gmomFlav, "gmomFlav");
0545 writeValueMap(iEvent, muons, hmomFlav, "hmomFlav");
0546 writeValueMap(iEvent, muons, signp, "signp");
0547 writeValueMap(iEvent, muons, pt, "pt");
0548 writeValueMap(iEvent, muons, eta, "eta");
0549 writeValueMap(iEvent, muons, phi, "phi");
0550 writeValueMap(iEvent, muons, prodRho, "prodRho");
0551 writeValueMap(iEvent, muons, prodZ, "prodZ");
0552 writeValueMap(iEvent, muons, momRho, "momRho");
0553 writeValueMap(iEvent, muons, momZ, "momZ");
0554 writeValueMap(iEvent, muons, tpAssoQuality, "tpAssoQuality");
0555
0556 if (linkToGenParticles_) {
0557 edm::OrphanHandle<reco::GenParticleCollection> secHandle = iEvent.put(std::move(secondaries), "secondaries");
0558 edm::RefProd<reco::GenParticleCollection> priRP(genParticles);
0559 edm::RefProd<reco::GenParticleCollection> secRP(secHandle);
0560 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outPri(
0561 new edm::Association<reco::GenParticleCollection>(priRP));
0562 std::unique_ptr<edm::Association<reco::GenParticleCollection> > outSec(
0563 new edm::Association<reco::GenParticleCollection>(secRP));
0564 edm::Association<reco::GenParticleCollection>::Filler fillPri(*outPri), fillSec(*outSec);
0565 fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
0566 fillSec.insert(muons, muToSecondary.begin(), muToSecondary.end());
0567 fillPri.fill();
0568 fillSec.fill();
0569 iEvent.put(std::move(outPri), "toPrimaries");
0570 iEvent.put(std::move(outSec), "toSecondaries");
0571 }
0572 }
0573
0574 template <typename T>
0575 void MuonMCClassifier::writeValueMap(edm::Event &iEvent,
0576 const edm::Handle<edm::View<reco::Muon> > &handle,
0577 const std::vector<T> &values,
0578 const std::string &label) const {
0579 using namespace edm;
0580 using namespace std;
0581 unique_ptr<ValueMap<T> > valMap(new ValueMap<T>());
0582 typename edm::ValueMap<T>::Filler filler(*valMap);
0583 filler.insert(handle, values.begin(), values.end());
0584 filler.fill();
0585 iEvent.put(std::move(valMap), label);
0586 }
0587
0588 int MuonMCClassifier::flavour(int pdgId) const {
0589 int flav = std::abs(pdgId);
0590
0591
0592 if (flav <= 37 && flav != 21)
0593 return flav;
0594
0595 int bflav = ((flav / 1000) % 10);
0596 if (bflav != 0)
0597 return bflav;
0598
0599 int mflav = ((flav / 100) % 10);
0600 if (mflav != 0)
0601 return mflav;
0602 return 0;
0603 }
0604
0605
0606
0607 int MuonMCClassifier::convertAndPush(const TrackingParticle &tp,
0608 reco::GenParticleCollection &out,
0609 const TrackingParticleRef &simMom,
0610 const edm::Handle<reco::GenParticleCollection> &genParticles) const {
0611 out.push_back(reco::GenParticle(tp.charge(), tp.p4(), tp.vertex(), tp.pdgId(), tp.status(), true));
0612 if (simMom.isNonnull() && !simMom->genParticles().empty()) {
0613 if (genParticles.id() != simMom->genParticles().id()) {
0614 throw cms::Exception("Configuration")
0615 << "Product ID mismatch between the genParticle collection (" << genParticles_ << ", id " << genParticles.id()
0616 << ") and the references in the TrackingParticles (id " << simMom->genParticles().id() << ")\n";
0617 }
0618 out.back().addMother(simMom->genParticles()[0]);
0619 }
0620 return out.size() - 1;
0621 }
0622
0623
0624 DEFINE_FWK_MODULE(MuonMCClassifier);