65 #include <boost/foreach.hpp>
66 #define foreach BOOST_FOREACH
108 const std::vector<T> &
values,
109 const std::string &
label)
const ;
112 if (tp.
isNonnull() && tp->parentVertex().
isNonnull() && !tp->parentVertex()->sourceTracks().empty()) {
113 return tp->parentVertex()->sourceTracks()[0];
121 const HepMC::GenVertex *vtx = gp->production_vertex();
122 if (vtx != 0 && vtx->particles_in_size() > 0) {
123 return *vtx->particles_in_const_begin();
130 int fetch(
const edm::Handle<std::vector<int> > & genBarcodes,
int barcode)
const;
139 const edm::Handle<std::vector<int> > & genBarcodes)
const ;
143 muons_(iConfig.getParameter<edm::InputTag>(
"muons")),
144 hasMuonCut_(iConfig.existsAs<std::string>(
"muonPreselection")),
145 muonCut_(hasMuonCut_ ? iConfig.getParameter<std::string>(
"muonPreselection") :
""),
146 trackingParticles_(iConfig.getParameter<edm::InputTag>(
"trackingParticles")),
147 associatorLabel_(iConfig.getParameter< std::string >(
"associatorLabel")),
148 decayRho_(iConfig.getParameter<double>(
"decayRho")),
149 decayAbsZ_(iConfig.getParameter<double>(
"decayAbsZ")),
150 linkToGenParticles_(iConfig.getParameter<bool>(
"linkToGenParticles")),
151 genParticles_(linkToGenParticles_ ? iConfig.getParameter<edm::InputTag>(
"genParticles") : edm::InputTag(
"NONE"))
153 std::string trackType = iConfig.
getParameter< std::string >(
"trackType");
158 else throw cms::Exception(
"Configuration") <<
"Track type '" << trackType <<
"' not supported.\n";
160 produces<edm::ValueMap<int> >();
161 produces<edm::ValueMap<int> >(
"ext");
162 produces<edm::ValueMap<int> >(
"flav");
163 produces<edm::ValueMap<int> >(
"hitsPdgId");
164 produces<edm::ValueMap<int> >(
"momPdgId");
165 produces<edm::ValueMap<int> >(
"momFlav");
166 produces<edm::ValueMap<int> >(
"momStatus");
167 produces<edm::ValueMap<int> >(
"gmomPdgId");
168 produces<edm::ValueMap<int> >(
"gmomFlav");
169 produces<edm::ValueMap<int> >(
"hmomFlav");
170 produces<edm::ValueMap<int> >(
"tpId");
171 produces<edm::ValueMap<float> >(
"prodRho");
172 produces<edm::ValueMap<float> >(
"prodZ");
173 produces<edm::ValueMap<float> >(
"momRho");
174 produces<edm::ValueMap<float> >(
"momZ");
175 produces<edm::ValueMap<float> >(
"tpAssoQuality");
177 produces<reco::GenParticleCollection>(
"secondaries");
178 produces<edm::Association<reco::GenParticleCollection> >(
"toPrimaries");
179 produces<edm::Association<reco::GenParticleCollection> >(
"toSecondaries");
208 if (assoByHits == 0)
throw cms::Exception(
"Configuration") <<
"The Track Associator with label '" <<
associatorLabel_ <<
"' is not a MuonAssociatorByHits.\n";
212 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
214 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
219 selMuons = muons->refVector();
223 for (
size_t i = 0,
n = muons->size();
i <
n; ++
i) {
230 for (
size_t i = 0,
n = trackingParticles->size();
i <
n; ++
i) {
240 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n ***************************************************************** ";
241 edm::LogVerbatim(
"MuonMCClassifier") <<
" STANDALONE (UpdAtVtx) MUON association ";
242 edm::LogVerbatim(
"MuonMCClassifier") <<
" ***************************************************************** \n";
244 allTPs, &iEvent, &iSetup);
247 typedef MuonAssociatorByHits::MuonToSimCollection::const_iterator r2s_it;
248 typedef MuonAssociatorByHits::SimToMuonCollection::const_iterator s2r_it;
250 size_t nmu = muons->size();
251 edm::LogVerbatim(
"MuonMCClassifier") <<
"\n There are "<<nmu<<
" reco::Muons.";
253 std::vector<int> classif(nmu, 0), ext(nmu, 0);
254 std::vector<int> hitsPdgId(nmu, 0), momPdgId(nmu, 0), gmomPdgId(nmu, 0), momStatus(nmu, 0);
255 std::vector<int> flav(nmu, 0), momFlav(nmu, 0), gmomFlav(nmu, 0), hmomFlav(nmu, 0);
256 std::vector<int> tpId(nmu, -1);
257 std::vector<float> prodRho(nmu, 0.0), prodZ(nmu, 0.0), momRho(nmu, 0.0), momZ(nmu, 0.0);
258 std::vector<float> tpAssoQuality(nmu, -1);
260 std::auto_ptr<reco::GenParticleCollection> secondaries;
261 std::map<TrackingParticleRef, int> tpToSecondaries;
262 std::vector<int> muToPrimary(nmu, -1), muToSecondary(nmu, -1);
265 for(
size_t i = 0;
i < nmu; ++
i) {
269 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t muon didn't pass the selection. classified as -99 and skipped";
270 classif[
i] = -99;
continue;
275 r2s_it
match = recSimColl.find(mu);
277 if (match != recSimColl.end()) {
280 tp = match->second.front().first;
282 tpAssoQuality[
i] = match->second.front().second;
283 s2r_it matchback = simRecColl.find(tp);
284 if (matchback != simRecColl.end()) {
285 muMatchBack = matchback->second.front().first;
287 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 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t RtS matched Ok... from the UpdSTA_recSimColl ";
295 tp = matchSta->second.front().first;
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;
302 edm::LogWarning(
"MuonMCClassifier") <<
"\n***WARNING: This I do NOT understand: why no match back in UpdSTA? *** \n";
307 bool isGhost = muMatchBack !=
mu;
308 if (isGhost)
edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems a GHOST ! classif[i] will be < 0";
310 hitsPdgId[
i] = tp->pdgId();
311 prodRho[
i] = tp->vertex().Rho();
312 prodZ[
i] = tp->vertex().Z();
313 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t TP pdgId = "<<hitsPdgId[
i] <<
", vertex rho = " << prodRho[
i] <<
", z = " << prodZ[
i];
317 if (!tp->genParticle().empty()) {
320 momPdgId[
i] = genMom->pdg_id();
321 momStatus[
i] = genMom->status();
322 if (genMom->production_vertex()) {
323 const HepMC::ThreeVector & momVtx = genMom->production_vertex()->point3d();
324 momRho[
i] = momVtx.perp() * 0.1; momZ[
i] = momVtx.z() * 0.1;
326 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t Particle pdgId = "<<hitsPdgId[
i] <<
" produced at rho = " << prodRho[
i] <<
", z = " << prodZ[
i] <<
", has GEN mother pdgId = " << momPdgId[
i];
329 gmomPdgId[
i] = genGMom->pdg_id();
330 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t mother prod. vertex rho = " << momRho[
i] <<
", z = " << momZ[
i] <<
", grand-mom pdgId = " << gmomPdgId[
i];
334 nMom != 0 &&
abs(nMom->pdg_id()) >= 100;
336 int flav =
flavour(nMom->pdg_id());
337 if (hmomFlav[
i] < flav) hmomFlav[
i] = flav;
338 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t backtracking flavour: mom pdgId = "<<nMom->pdg_id()<<
", flavour = " << flav <<
", heaviest so far = " << hmomFlav[
i];
344 momPdgId[
i] = simMom->pdgId();
345 momRho[
i] = simMom->vertex().Rho();
346 momZ[
i] = simMom->vertex().Z();
347 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t Particle pdgId = "<<hitsPdgId[
i] <<
" produced at rho = " << prodRho[
i] <<
", z = " << prodZ[
i] <<
348 ", has SIM mother pdgId = " << momPdgId[
i] <<
" produced at rho = " << simMom->vertex().Rho() <<
", z = " << simMom->vertex().Z();
349 if (!simMom->genParticle().empty()) {
350 momStatus[
i] = simMom->genParticle()[0]->status();
352 if (genGMom) gmomPdgId[
i] = genGMom->pdg_id();
353 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t SIM mother is in GEN (status " << momStatus[
i] <<
"), grand-mom id = " << gmomPdgId[
i];
357 if (simGMom.
isNonnull()) gmomPdgId[
i] = simGMom->pdgId();
358 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t\t SIM mother is in SIM only, grand-mom id = " << gmomPdgId[
i];
361 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t Particle pdgId = "<<hitsPdgId[
i] <<
" produced at rho = " << prodRho[
i] <<
", z = " << prodZ[
i] <<
", has NO mother!";
365 gmomFlav[
i] =
flavour(gmomPdgId[i]);
368 if (
abs(tp->pdgId()) != 13) {
369 classif[
i] = isGhost ? -1 : 1;
370 ext[
i] = isGhost ? -1 : 1;
371 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This is not a muon. Sorry. classif[i] = " << classif[
i];
376 if (!tp->genParticle().empty() && (momPdgId[
i] != 0)) {
377 if (
abs(momPdgId[i]) < 100 && (
abs(momPdgId[i]) != 15)) {
378 classif[
i] = isGhost ? -4 : 4;
379 flav[
i] = (
abs(momPdgId[i]) == 15 ? 15 : 13);
380 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems PRIMARY MUON ! classif[i] = " << classif[
i];
382 }
else if (momFlav[i] == 4 || momFlav[i] == 5 || momFlav[i] == 15) {
383 classif[
i] = isGhost ? -3 : 3;
384 flav[
i] = momFlav[
i];
385 if (momFlav[i] == 15) ext[
i] = 9;
386 else if (momFlav[i] == 5) ext[
i] = 8;
387 else if (hmomFlav[i] == 5) ext[
i] = 7;
389 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems HEAVY FLAVOUR ! classif[i] = " << classif[
i];
391 classif[
i] = isGhost ? -2 : 2;
392 flav[
i] = momFlav[
i];
393 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
396 classif[
i] = isGhost ? -2 : 2;
397 flav[
i] = momFlav[
i];
398 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t This seems LIGHT FLAVOUR ! classif[i] = " << classif[
i];
401 if (momPdgId[i] == 0) ext[
i] = 2;
402 else if (
abs(momPdgId[i]) < 100) ext[
i] = (momFlav[
i] == 15 ? 9 : 10);
403 else if (momFlav[i] == 5) ext[
i] = 8;
404 else if (momFlav[i] == 4) ext[
i] = (hmomFlav[
i] == 5 ? 7 : 6);
405 else if (momStatus[i] != -1) {
406 int id =
abs(momPdgId[i]);
407 if (
id != 211 &&
id != 321 &&
id != 130 ) ext[
i] = 5;
411 if (isGhost) ext[
i] = -ext[
i];
415 if (!tp->genParticle().empty() &&
abs(ext[i]) >= 5) {
416 muToPrimary[
i] =
fetch(genBarcodes, tp->genParticle()[0]->barcode());
419 int &indexPlus1 = tpToSecondaries[tp];
421 muToSecondary[
i] = indexPlus1 - 1;
424 edm::LogVerbatim(
"MuonMCClassifier") <<
"\t Extended classification code = " << ext[
i];
443 writeValueMap(iEvent, muons, tpAssoQuality,
"tpAssoQuality");
452 fillPri.insert(muons, muToPrimary.begin(), muToPrimary.end());
453 fillSec.
insert(muons, muToSecondary.begin(), muToSecondary.end());
454 fillPri.fill(); fillSec.
fill();
455 iEvent.
put(outPri,
"toPrimaries");
456 iEvent.
put(outSec,
"toSecondaries");
464 const std::vector<T> &
values,
465 const std::string &
label)
const
473 iEvent.
put(valMap, label);
478 int flav =
abs(pdgId);
481 if (flav <= 37 && flav != 21)
return flav;
483 int bflav = ((flav / 1000) % 10);
484 if (bflav != 0)
return bflav;
486 int mflav = ((flav / 100) % 10);
487 if (mflav != 0)
return mflav;
493 std::vector<int>::const_iterator it =
std::find(genBarcodes->begin(), genBarcodes->end(), barcode);
494 return (it == genBarcodes->end()) ? -1 : (it - genBarcodes->begin());
503 const edm::Handle<std::vector<int> > & genBarcodes)
const {
505 if (simMom.
isNonnull() && !simMom->genParticle().empty()) {
506 int momIdx =
fetch(genBarcodes, simMom->genParticle()[0]->barcode());
edm::InputTag genParticles_
bool linkToGenParticles_
Create a link to the generator level particles.
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
int charge() const
electric charge
#define DEFINE_FWK_MODULE(type)
void associateMuons(MuonToSimCollection &recoToSim, SimToMuonCollection &simToReco, const edm::RefToBaseVector< reco::Muon > &, MuonTrackType, const edm::RefVector< TrackingParticleCollection > &, const edm::Event *event=0, const edm::EventSetup *setup=0) const
int pdgId() const
PDG id, signal source, crossing number.
void insert(const H &h, I begin, I end)
const_iterator end() const
bool isGlobalMuon() const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
edm::InputTag trackingParticles_
The TrackingParticle objects.
bool isNonnull() const
Checks for non-null.
std::map< TrackingParticleRef, std::vector< std::pair< edm::RefToBase< reco::Muon >, double > > > SimToMuonCollection
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
int fetch(const edm::Handle< std::vector< int > > &genBarcodes, int barcode) const
Find the index of a genParticle given it's barcode. -1 if not found.
int convertAndPush(const TrackingParticle &tp, reco::GenParticleCollection &out, const TrackingParticleRef &momRef, const edm::Handle< reco::GenParticleCollection > &genParticles, const edm::Handle< std::vector< int > > &genBarcodes) const
TrackingParticleRef getTpMother(TrackingParticleRef tp)
MuonMCClassifier(const edm::ParameterSet &)
std::string associatorLabel_
The Associations.
const LorentzVector & p4() const
four-momentum Lorentz vector
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
int status() const
status word
MuonAssociatorByHits::MuonTrackType trackType_
Track to use.
key_type key() const
Accessor for product key.
T const * product() 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.
virtual void produce(edm::Event &, const edm::EventSetup &)
const_iterator begin() const
double decayRho_
Cylinder to use to decide if a decay is early or late.
void push_back(const RefToBase< T > &)
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
edm::InputTag muons_
The RECO objects.
T const * get() const
Returns C++ pointer to the item.
const Point & vertex() const
vertex position
int flavour(int pdgId) const
Returns the flavour given a pdg id code.
Analysis-level muon class.
std::map< edm::RefToBase< reco::Muon >, std::vector< std::pair< TrackingParticleRef, double > >, RefToBaseSort > MuonToSimCollection
edm::Ref< TrackingParticleCollection > TrackingParticleRef
const HepMC::GenParticle * getGpMother(const HepMC::GenParticle *gp)
StringCutObjectSelector< pat::Muon > muonCut_