CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonPFCandidateCleaner.cc
Go to the documentation of this file.
1 
21 
23 
27 
29 
30 #include <vector>
31 #include <algorithm>
32 
34 {
35  public:
38 
39  private:
40  virtual void produce(edm::Event&, const edm::EventSetup&);
41 
44 
45  double dRmatch_;
47 
52 
54 };
55 
57  : srcSelectedMuons_(cfg.getParameter<edm::InputTag>("selectedMuons")),
58  srcPFCandidates_(cfg.getParameter<edm::InputTag>("pfCands")),
59  dRmatch_(cfg.getParameter<double>("dRmatch")),
60  removeDuplicates_(cfg.getParameter<bool>("removeDuplicates")),
61  maxWarnings_tooMany_(100),
62  numWarnings_tooMany_(0),
63  maxWarnings_tooFew_(3),
64  numWarnings_tooFew_(0)
65 {
66  verbosity_ = ( cfg.exists("verbosity") ) ?
67  cfg.getParameter<int>("verbosity") : 0;
68 
69  produces<reco::PFCandidateCollection>();
70 }
71 
72 namespace
73 {
74  struct muonToPFCandMatchInfoType
75  {
76  muonToPFCandMatchInfoType(const reco::Particle::LorentzVector& muonP4, const reco::PFCandidate* pfCandidate, double dR)
77  : muonPt_(muonP4.pt()),
78  pfCandidatePt_(pfCandidate->pt()),
79  pfCandidateCharge_(pfCandidate->charge()),
80  dR_(dR),
81  pfCandidate_(pfCandidate)
82  {}
83  ~muonToPFCandMatchInfoType() {}
84  double muonPt_;
85  double pfCandidatePt_;
86  int pfCandidateCharge_;
87  double dR_;
89  };
90 
91  struct SortMuonToPFCandMatchInfosDescendingMatchQuality
92  {
93  bool operator() (const muonToPFCandMatchInfoType& m1, const muonToPFCandMatchInfoType& m2)
94  {
95  // 1st criterion: prefer matches of high Pt
96  if ( m1.pfCandidatePt_ > (0.5*m1.muonPt_) && m2.pfCandidatePt_ < (0.5*m2.muonPt_) ) return true; // m1 has higher rank than m2
97  if ( m1.pfCandidatePt_ < (0.5*m1.muonPt_) && m2.pfCandidatePt_ > (0.5*m2.muonPt_) ) return false; // m2 has higher rank than m1
98  // 2nd criterion: prefer matches to charged particles
99  if ( m1.pfCandidateCharge_ != 0 && m2.pfCandidateCharge_ == 0 ) return true;
100  if ( m1.pfCandidateCharge_ == 0 && m2.pfCandidateCharge_ != 0 ) return false;
101  // 3rd criterion: in case multiple matches to high Pt, charged particles exist,
102  // take particle matched most closely in dR
103  return (m1.dR_ < m2.dR_);
104  }
105  };
106 
107  std::string runLumiEventNumbers_to_string(const edm::Event& evt)
108  {
109  edm::RunNumber_t run_number = evt.id().run();
111  edm::EventNumber_t event_number = evt.id().event();
112  std::ostringstream retVal;
113  retVal << "Run = " << run_number << ", LS = " << ls_number << ", Event = " << event_number;
114  return retVal.str();
115  }
116 }
117 
119 {
120  if ( verbosity_ ) std::cout << "<MuonPFCandidateCleaner::produce>:" << std::endl;
121 
122  std::vector<reco::CandidateBaseRef> selMuons = getSelMuons(evt, srcSelectedMuons_);
123  const reco::CandidateBaseRef muPlus = getTheMuPlus(selMuons);
124  const reco::CandidateBaseRef muMinus = getTheMuMinus(selMuons);
125 
126  std::vector<reco::Particle::LorentzVector> selMuonP4s;
127  if ( muPlus.isNonnull() ) {
128  if ( verbosity_ ) std::cout << " muPlus: Pt = " << muPlus->pt() << ", eta = " << muPlus->eta() << ", phi = " << muPlus->phi() << std::endl;
129  selMuonP4s.push_back(muPlus->p4());
130  }
131  if ( muMinus.isNonnull() ) {
132  if ( verbosity_ ) std::cout << " muMinus: Pt = " << muMinus->pt() << ", eta = " << muMinus->eta() << ", phi = " << muMinus->phi() << std::endl;
133  selMuonP4s.push_back(muMinus->p4());
134  }
135 
136 //--- produce collection of PFCandidate excluding muons
138  evt.getByLabel(srcPFCandidates_, pfCandidates);
139 
140  std::auto_ptr<reco::PFCandidateCollection> pfCandidates_woMuons(new reco::PFCandidateCollection());
141 
142 //--- iterate over list of reconstructed PFCandidates,
143 // add PFCandidate to output collection in case it does not correspond to any selected muon
144  std::vector<muonToPFCandMatchInfoType> selMuonToPFCandMatches;
145  for ( std::vector<reco::Particle::LorentzVector>::const_iterator selMuonP4 = selMuonP4s.begin();
146  selMuonP4 != selMuonP4s.end(); ++selMuonP4 ) {
147  std::vector<muonToPFCandMatchInfoType> tmpMatches;
148  for ( reco::PFCandidateCollection::const_iterator pfCandidate = pfCandidates->begin();
149  pfCandidate != pfCandidates->end(); ++pfCandidate ) {
150  double dR = reco::deltaR(pfCandidate->p4(), *selMuonP4);
151  if ( dR < dRmatch_ ) tmpMatches.push_back(muonToPFCandMatchInfoType(*selMuonP4, &(*pfCandidate), dR));
152  }
153  // rank muon-to-pfCandidate matches by quality
154  std::sort(tmpMatches.begin(), tmpMatches.end(), SortMuonToPFCandMatchInfosDescendingMatchQuality());
155  if ( tmpMatches.size() > 0 ) selMuonToPFCandMatches.push_back(tmpMatches.front());
156  if ( removeDuplicates_ ) {
157  // CV: remove all high Pt charged PFCandidates very close to muon direction
158  // (duplicate tracks arise in case muon track in SiStrip + Pixel detector is reconstructed as 2 disjoint segments)
159  for ( std::vector<muonToPFCandMatchInfoType>::const_iterator tmpMatch = tmpMatches.begin();
160  tmpMatch != tmpMatches.end(); ++tmpMatch ) {
161  if ( tmpMatch->dR_ < 1.e-3 && fabs(tmpMatch->pfCandidateCharge_) > 0.5 && tmpMatch->pfCandidatePt_ > (0.33*tmpMatch->muonPt_) ) selMuonToPFCandMatches.push_back(*tmpMatch);
162  }
163  }
164  }
165 
166  std::vector<const reco::PFCandidate*> removedPFCandidates;
167  for ( reco::PFCandidateCollection::const_iterator pfCandidate = pfCandidates->begin();
168  pfCandidate != pfCandidates->end(); ++pfCandidate ) {
169  bool isMuon = false;
170  for ( std::vector<muonToPFCandMatchInfoType>::const_iterator muonMatchInfo = selMuonToPFCandMatches.begin();
171  muonMatchInfo != selMuonToPFCandMatches.end(); ++muonMatchInfo ) {
172  if ( muonMatchInfo->pfCandidate_ == &(*pfCandidate) ) isMuon = true;
173  }
174  if ( verbosity_ && pfCandidate->pt() > 10. && fabs(pfCandidate->charge()) > 0.5 ) {
175  std::cout << "pfCandidate: Pt = " << pfCandidate->pt() << ", eta = " << pfCandidate->eta() << ", phi = " << pfCandidate->phi() << ", isMuon = " << isMuon << std::endl;
176  }
177  if ( isMuon ) removedPFCandidates.push_back(&(*pfCandidate)); // pfCandidate belongs to a selected muon, do not copy
178  else pfCandidates_woMuons->push_back(*pfCandidate);
179  }
180  if ( (removedPFCandidates.size() > selMuons.size() && numWarnings_tooMany_ < maxWarnings_tooMany_) &&
181  (removedPFCandidates.size() < selMuons.size() && numWarnings_tooFew_ < maxWarnings_tooFew_ ) ) {
182  edm::LogWarning("MuonPFCandidateCleaner")
183  << " (" << runLumiEventNumbers_to_string(evt) << ")" << std::endl
184  << " Removed " << removedPFCandidates.size() << " PF-candidates from event containing " << selMuons.size() << " muons !!" << std::endl;
185  if ( muPlus.isNonnull() ) std::cout << " muPlus: Pt = " << muPlus->pt() << ", eta = " << muPlus->eta() << ", phi = " << muPlus->phi() << std::endl;
186  if ( muMinus.isNonnull() ) std::cout << " muMinus: Pt = " << muMinus->pt() << ", eta = " << muMinus->eta() << ", phi = " << muMinus->phi() << std::endl;
187  int idx = 0;
188  for ( std::vector<const reco::PFCandidate*>::const_iterator removedPFCandidate = removedPFCandidates.begin();
189  removedPFCandidate != removedPFCandidates.end(); ++removedPFCandidate ) {
190  std::cout << "PF-candidate #" << idx << " (charge = " << (*removedPFCandidate)->charge() << "):"
191  << " Pt = " << (*removedPFCandidate)->pt() << ", eta = " << (*removedPFCandidate)->eta() << ", phi = " << (*removedPFCandidate)->phi() << std::endl;
192  ++idx;
193  }
194  if ( removedPFCandidates.size() > selMuons.size() ) ++numWarnings_tooMany_;
195  if ( removedPFCandidates.size() < selMuons.size() ) ++numWarnings_tooFew_;
196  }
197 
198  evt.put(pfCandidates_woMuons);
199 }
200 
202 
RunNumber_t run() const
Definition: EventID.h:39
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
reco::CandidateBaseRef getTheMuMinus(const std::vector< reco::CandidateBaseRef > &)
tuple cfg
Definition: looper.py:293
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:11
virtual double pt() const =0
transverse momentum
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
reco::PFCandidatePtr pfCandidate_
bool exists(std::string const &parameterName) const
checks if a parameter exists
unsigned long long EventNumber_t
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:62
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:322
unsigned int LuminosityBlockNumber_t
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
virtual void produce(edm::Event &, const edm::EventSetup &)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:418
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
edm::EventID id() const
Definition: EventBase.h:59
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
tuple cout
Definition: gather_cfg.py:145
unsigned int RunNumber_t
std::vector< reco::CandidateBaseRef > getSelMuons(const edm::Event &, const edm::InputTag &)
reco::CandidateBaseRef getTheMuPlus(const std::vector< reco::CandidateBaseRef > &)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
MuonPFCandidateCleaner(const edm::ParameterSet &)
virtual double phi() const =0
momentum azimuthal angle
virtual double eta() const =0
momentum pseudorapidity
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector