CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonRadiationFilter.cc
Go to the documentation of this file.
2 
11 
13 
14 #include <TMath.h>
15 
16 const double nomMassZ = 91.1876;
17 
19 {
20  srcSelectedMuons_ = cfg.getParameter<edm::InputTag>("srcSelectedMuons");
21  srcPFCandsNoPU_ = cfg.getParameter<edm::InputTag>("srcPFCandsNoPU");
22  srcPFCandsPU_ = cfg.getParameter<edm::InputTag>("srcPFCandsPU");
23 
24  minPtLow_ = cfg.getParameter<double>("minPtLow");
25  dRlowPt_ = cfg.getParameter<double>("dRlowPt");
26  addCaloEnECALlowPt_ = cfg.getParameter<bool>("addCaloEnECALlowPt");
27  applyMassWindowSelectionLowPt_ = cfg.getParameter<bool>("applyMassWindowSelectionLowPt");
28 
29  minPtHigh_ = cfg.getParameter<double>("minPtHigh");
30  dRhighPt_ = cfg.getParameter<double>("dRhighPt");
31  addCaloEnECALhighPt_ = cfg.getParameter<bool>("addCaloEnECALhighPt");
32  applyMassWindowSelectionHighPt_ = cfg.getParameter<bool>("applyMassWindowSelectionHighPt");
33 
34  dRvetoCone_ = cfg.getParameter<double>("dRvetoCone");
35  dRisoCone_ = cfg.getParameter<double>("dRisoCone");
36  maxRelIso_ = cfg.getParameter<double>("maxRelIso");
37 
38  maxMass_ = cfg.getParameter<double>("maxMass");
39 
40  invert_ = cfg.getParameter<bool>("invert");
41  filter_ = cfg.getParameter<bool>("filter");
42  if ( !filter_ ) {
43  produces<bool>();
44  }
45 
46  verbosity_ = ( cfg.exists("verbosity") ) ?
47  cfg.getParameter<int>("verbosity") : 0;
48 }
49 
50 namespace
51 {
52  reco::Candidate::LorentzVector makeCaloEnP4(const reco::Candidate::LorentzVector& refP4, double caloEn)
53  {
54  double ux = TMath::Cos(refP4.phi())*TMath::Sin(refP4.theta());
55  double uy = TMath::Sin(refP4.phi())*TMath::Sin(refP4.theta());
56  double uz = TMath::Cos(refP4.theta());
57  reco::Candidate::LorentzVector p4(ux*caloEn, uy*caloEn, uz*caloEn, caloEn);
58  return p4;
59  }
60 }
61 
63 {
64  if ( verbosity_ ) std::cout << "<MuonRadiationFilter::filter>:" << std::endl;
65 
66  std::vector<reco::CandidateBaseRef> selMuons = getSelMuons(evt, srcSelectedMuons_);
67  const reco::CandidateBaseRef muPlus = getTheMuPlus(selMuons);
68  const reco::CandidateBaseRef muMinus = getTheMuMinus(selMuons);
69 
70  if ( muPlus.isNull() || muMinus.isNull() ) return false; // not selected Z --> mu+ mu- event: reject event
71 
72  edm::Handle<PFView> pfCandidatesNoPU;
73  evt.getByLabel(srcPFCandsNoPU_, pfCandidatesNoPU);
74  edm::Handle<PFView> pfCandidatesPU;
75  evt.getByLabel(srcPFCandsPU_, pfCandidatesPU);
76 
77  double muPlusCaloEnECAL = compCaloEnECAL(muPlus->p4(), *pfCandidatesNoPU);
78  if ( verbosity_ ) std::cout << "muPlusCaloEnECAL = " << muPlusCaloEnECAL << std::endl;
79  reco::Candidate::LorentzVector caloP4muPlus = makeCaloEnP4(muPlus->p4(), muPlusCaloEnECAL);
80  double muMinusCaloEnECAL = compCaloEnECAL(muMinus->p4(), *pfCandidatesNoPU);
81  if ( verbosity_ ) std::cout << "muMinusCaloEnECAL = " << muMinusCaloEnECAL << std::endl;
82  reco::Candidate::LorentzVector caloP4muMinus = makeCaloEnP4(muMinus->p4(), muMinusCaloEnECAL);
83 
84  bool isMuonRadiation = false;
85 
86  for ( PFView::const_iterator pfCandidate = pfCandidatesNoPU->begin();
87  pfCandidate != pfCandidatesNoPU->end(); ++pfCandidate ) {
88  if ( (*pfCandidate)->particleId() == reco::PFCandidate::gamma || (*pfCandidate)->particleId() == reco::PFCandidate::e ) { // CV: include converted photons
89  double dRmuPlus = deltaR((*pfCandidate)->p4(), muPlus->p4());
90  if ( checkMuonRadiation((*pfCandidate)->p4(), &caloP4muPlus, dRmuPlus, *pfCandidatesNoPU, *pfCandidatesPU, *muPlus, *muMinus) ) isMuonRadiation = true;
91  double dRmuMinus = deltaR((*pfCandidate)->p4(), muMinus->p4());
92  if ( checkMuonRadiation((*pfCandidate)->p4(), &caloP4muMinus, dRmuMinus, *pfCandidatesNoPU, *pfCandidatesPU, *muPlus, *muMinus) ) isMuonRadiation = true;
93  }
94  }
95 
96  if ( checkMuonRadiation(caloP4muPlus, 0, 0., *pfCandidatesNoPU, *pfCandidatesPU, *muPlus, *muMinus) ) isMuonRadiation = true;
97  if ( checkMuonRadiation(caloP4muMinus, 0, 0., *pfCandidatesNoPU, *pfCandidatesPU, *muPlus, *muMinus) ) isMuonRadiation = true;
98 
99  if ( verbosity_ ) std::cout << "isMuonRadiation = " << isMuonRadiation << std::endl;
100 
101  if ( filter_ ) {
102  if ( invert_ != isMuonRadiation ) return false; // reject events with muon -> muon + photon radiation
103  else return true;
104  } else {
105  std::auto_ptr<bool> filter_result(new bool(invert_ != !isMuonRadiation));
106  evt.put(filter_result);
107  return true;
108  }
109 }
110 
112 {
113  double caloEnECAL = 0.;
114  for ( PFView::const_iterator pfCandidate = pfCandidates.begin();
115  pfCandidate != pfCandidates.end(); ++pfCandidate ) {
116  double dR = deltaR(refP4, (*pfCandidate)->p4());
117  if ( dR < dRvetoCone_ ) {
118  caloEnECAL += (*pfCandidate)->ecalEnergy();
119  }
120  }
121  return caloEnECAL;
122 }
123 
125  const PFView& pfCandidates,
126  const reco::Candidate::LorentzVector& muPlusP4, const reco::Candidate::LorentzVector& muMinusP4,
127  double& pfChargedCandIsoSum, double& pfGammaIsoSum, double& pfNeutralHadronIsoSum)
128 {
129  pfChargedCandIsoSum = 0.;
130  pfGammaIsoSum = 0.;
131  pfNeutralHadronIsoSum = 0.;
132  for ( PFView::const_iterator pfCandidate = pfCandidates.begin();
133  pfCandidate != pfCandidates.end(); ++pfCandidate ) {
134  double dR = deltaR(refP4, (*pfCandidate)->p4());
135  if ( dR < dRisoCone_ ) {
136  bool isVeto = false;
137  if ( dR < dRvetoCone_ ) {
138  isVeto = true;
139  } else {
140  double dRmuPlus = deltaR(muPlusP4, (*pfCandidate)->p4());
141  if ( dRmuPlus < dRvetoCone_ ) isVeto = true;
142  double dRmuMinus = deltaR(muMinusP4, (*pfCandidate)->p4());
143  if ( dRmuMinus < dRvetoCone_ ) isVeto = true;
144  }
145  if ( isVeto ) continue;
146  if ( TMath::Abs((*pfCandidate)->charge()) > 0.5 ) {
147  if ( verbosity_ ) std::cout << " adding PFChargedCand: Pt = " << (*pfCandidate)->pt() << ", eta = " << (*pfCandidate)->eta() << ", phi = " << (*pfCandidate)->phi() << " (dR = " << dR << ")" << std::endl;
148  pfChargedCandIsoSum += (*pfCandidate)->pt();
149  } else if ( (*pfCandidate)->particleId() == reco::PFCandidate::gamma ) {
150  if ( verbosity_ ) std::cout << " adding PFGamma: Pt = " << (*pfCandidate)->pt() << ", eta = " << (*pfCandidate)->eta() << ", phi = " << (*pfCandidate)->phi() << " (dR = " << dR << ")" << std::endl;
151  pfGammaIsoSum += (*pfCandidate)->pt();
152  } else if ( (*pfCandidate)->particleId() == reco::PFCandidate::h0 ) {
153  if ( verbosity_ ) std::cout << " adding PFNeutralHadron: Pt = " << (*pfCandidate)->pt() << ", eta = " << (*pfCandidate)->eta() << ", phi = " << (*pfCandidate)->phi() << " (dR = " << dR << ")" << std::endl;
154  pfNeutralHadronIsoSum += (*pfCandidate)->pt();
155  }
156  }
157  }
158 }
159 
161  const PFView& pfCandidatesNoPU, const PFView& pfCandidatesPU,
162  const reco::Candidate::LorentzVector& muPlusP4, const reco::Candidate::LorentzVector& muMinusP4)
163 {
164  if ( verbosity_ ) std::cout << "computing isoSum(NoPU)" << std::endl;
165  double pfChargedCandIsoSumNoPU, pfGammaIsoSumNoPU, pfNeutralHadronIsoSumNoPU;
166  compPFIso_raw(refP4, pfCandidatesNoPU, muPlusP4, muMinusP4, pfChargedCandIsoSumNoPU, pfGammaIsoSumNoPU, pfNeutralHadronIsoSumNoPU);
167 
168  if ( verbosity_ ) std::cout << "computing isoSum(PU)" << std::endl;
169  double pfChargedCandIsoSumPU, pfGammaIsoSumPU, pfNeutralHadronIsoSumPU;
170  compPFIso_raw(refP4, pfCandidatesPU, muPlusP4, muMinusP4, pfChargedCandIsoSumPU, pfGammaIsoSumPU, pfNeutralHadronIsoSumPU);
171 
172  // apply delta-beta PU correction to isolation Pt sum
173  double pfIso = pfChargedCandIsoSumNoPU + TMath::Max(0., pfGammaIsoSumNoPU + pfNeutralHadronIsoSumNoPU - 0.5*pfChargedCandIsoSumPU);
174  if ( verbosity_ ) {
175  std::cout << " pfChargedCandIsoSumNoPU = " << pfChargedCandIsoSumNoPU << std::endl;
176  std::cout << " pfGammaIsoSumNoPU = " << pfGammaIsoSumNoPU << std::endl;
177  std::cout << " pfNeutralHadronIsoSumNoPU = " << pfNeutralHadronIsoSumNoPU << std::endl;
178  std::cout << " pfChargedCandIsoSumPU = " << pfChargedCandIsoSumPU << std::endl;
179  std::cout << "--> isolation of PFGamma = " << pfIso << std::endl;
180  }
181  return pfIso;
182 }
183 
184 namespace
185 {
186  reco::Candidate::LorentzVector makeMuonP4(const reco::Candidate& muon_candidate, int verbosity)
187  {
188  const reco::Track* muonTrack = 0;
189  if ( dynamic_cast<const reco::Muon*>(&muon_candidate) ) {
190  const reco::Muon* muon = dynamic_cast<const reco::Muon*>(&muon_candidate);
191  if ( muon->innerTrack().isNonnull() ) muonTrack = muon->innerTrack().get();
192  else if ( muon->globalTrack().isNonnull() ) muonTrack = muon->globalTrack().get();
193  else if ( muon->outerTrack().isNonnull() ) muonTrack = muon->outerTrack().get();
194  } else if( dynamic_cast<const reco::PFCandidate*>(&muon_candidate) ) {
195  const reco::PFCandidate* pfCandidate = dynamic_cast<const reco::PFCandidate*>(&muon_candidate);
196  if ( pfCandidate->muonRef().isNonnull() ) return makeMuonP4(*pfCandidate->muonRef(), verbosity);
197  else if ( pfCandidate->trackRef().isNonnull() ) muonTrack = pfCandidate->trackRef().get();
198  else if ( pfCandidate->gsfTrackRef().isNonnull() ) muonTrack = pfCandidate->gsfTrackRef().get();
199  } else if ( muon_candidate.hasMasterClone() ) {
200  return makeMuonP4(*muon_candidate.masterClone(), verbosity);
201  } else if ( muon_candidate.hasMasterClonePtr() ) {
202  return makeMuonP4(*muon_candidate.masterClonePtr(), verbosity);
203  }
204  if ( muonTrack ) {
205  double muonP = muonTrack->p();
206  double muonPx = muonP*TMath::Cos(muon_candidate.phi())*TMath::Sin(muon_candidate.theta());
207  double muonPy = muonP*TMath::Sin(muon_candidate.phi())*TMath::Sin(muon_candidate.theta());
208  double muonPz = muonP*TMath::Cos(muon_candidate.theta());
209  const double muonMass = 0.10566; // GeV
210  double muonEn = TMath::Sqrt(muonP*muonP + muonMass*muonMass);
211  reco::Candidate::LorentzVector muonP4(muonPx, muonPy, muonPz, muonEn);
212  if ( verbosity ) {
213  std::cout << "muon (original): Pt = " << muon_candidate.pt() << ", eta = " << muon_candidate.eta() << ", phi = " << muon_candidate.phi() << std::endl;
214  std::cout << "muon (from track): Pt = " << muonP4.pt() << ", eta = " << muonP4.eta() << ", phi = " << muonP4.phi() << std::endl;
215  }
216  return muonP4;
217  } else {
218  return muon_candidate.p4();
219  }
220  }
221 }
222 
224  const PFView& pfCandidatesNoPU, const PFView& pfCandidatesPU,
225  const reco::Candidate& muPlus, const reco::Candidate& muMinus)
226 {
227  bool isMuonRadiation = false;
228  if ( dR < dRlowPt_ || dR < dRhighPt_ ) {
229  reco::Candidate::LorentzVector muPlusP4_fromTrack = makeMuonP4(muPlus, verbosity_);
230  reco::Candidate::LorentzVector muMinusP4_fromTrack = makeMuonP4(muMinus, verbosity_);
231  double massWithoutPhoton = (muPlusP4_fromTrack + muMinusP4_fromTrack).mass();
232  reco::Candidate::LorentzVector photonP4sumLow = photonP4;
233  if ( addCaloEnECALlowPt_ && caloP4mu ) photonP4sumLow += (*caloP4mu);
234  if ( dR < dRlowPt_ && photonP4sumLow.pt() > minPtLow_ ) {
235  double massWithPhoton = (muPlusP4_fromTrack + muMinusP4_fromTrack + photonP4sumLow).mass();
236  if ( verbosity_ ) {
237  std::cout << "low photon Pt threshold:" << std::endl;
238  std::cout << " muon #1:" << "Pt = " << muPlusP4_fromTrack.pt() << ", eta = " << muPlusP4_fromTrack.eta() << ", phi = " << muPlusP4_fromTrack.phi() << std::endl;
239  std::cout << " muon #2:" << "Pt = " << muMinusP4_fromTrack.pt() << ", eta = " << muMinusP4_fromTrack.eta() << ", phi = " << muMinusP4_fromTrack.phi() << std::endl;
240  std::cout << " photon:" << "Pt = " << photonP4sumLow.pt() << ", eta = " << photonP4sumLow.eta() << ", phi = " << photonP4sumLow.phi() << " (dR = " << dR << ")" << std::endl;
241  std::cout << " M(mu+mu) = " << massWithoutPhoton << ", M(mu+mu+gamma) = " << massWithPhoton << std::endl;
242  }
243  if ( (TMath::Abs(massWithPhoton - nomMassZ) < TMath::Abs(massWithoutPhoton - nomMassZ) && massWithPhoton < maxMass_) || !applyMassWindowSelectionLowPt_ ) {
244  double pfIso = compPFIso_puCorr(photonP4sumLow, pfCandidatesNoPU, pfCandidatesPU, muPlus.p4(), muMinus.p4());
245  if ( pfIso < (maxRelIso_*photonP4sumLow.pt()) ) isMuonRadiation = true;
246  }
247  }
248  reco::Candidate::LorentzVector photonP4sumHigh = photonP4;
249  if ( addCaloEnECALhighPt_ && caloP4mu ) photonP4sumHigh += (*caloP4mu);
250  if ( dR < dRhighPt_ && photonP4sumHigh.pt() > minPtHigh_ ) {
251  double massWithPhoton = (muPlusP4_fromTrack + muMinusP4_fromTrack + photonP4sumHigh).mass();
252  if ( verbosity_ ) {
253  std::cout << "high photon Pt threshold:" << std::endl;
254  std::cout << " muon #1:" << "Pt = " << muPlusP4_fromTrack.pt() << ", eta = " << muPlusP4_fromTrack.eta() << ", phi = " << muPlusP4_fromTrack.phi() << std::endl;
255  std::cout << " muon #2:" << "Pt = " << muMinusP4_fromTrack.pt() << ", eta = " << muMinusP4_fromTrack.eta() << ", phi = " << muMinusP4_fromTrack.phi() << std::endl;
256  std::cout << " photon:" << "Pt = " << photonP4sumHigh.pt() << ", eta = " << photonP4sumHigh.eta() << ", phi = " << photonP4sumHigh.phi() << " (dR = " << dR << ")" << std::endl;
257  std::cout << " M(mu+mu) = " << massWithoutPhoton << ", M(mu+mu+gamma) = " << massWithPhoton << std::endl;
258  }
259  if ( (TMath::Abs(massWithPhoton - nomMassZ) < TMath::Abs(massWithoutPhoton - nomMassZ) && massWithPhoton < maxMass_) || !applyMassWindowSelectionHighPt_ ) {
260  double pfIso = compPFIso_puCorr(photonP4sumHigh, pfCandidatesNoPU, pfCandidatesPU, muPlus.p4(), muMinus.p4());
261  if ( pfIso < (maxRelIso_*photonP4sumHigh.pt()) ) isMuonRadiation = true;
262  }
263  }
264  }
265  return isMuonRadiation;
266 }
267 
269 
double p() const
momentum vector magnitude
Definition: TrackBase.h:602
T getParameter(std::string const &) const
reco::CandidateBaseRef getTheMuMinus(const std::vector< reco::CandidateBaseRef > &)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
tuple cfg
Definition: looper.py:293
virtual TrackRef innerTrack() const
Definition: Muon.h:48
virtual double pt() const =0
transverse momentum
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool checkMuonRadiation(const reco::Candidate::LorentzVector &, const reco::Candidate::LorentzVector *, double, const PFView &, const PFView &, const reco::Candidate &, const reco::Candidate &)
virtual const CandidatePtr & masterClonePtr() const =0
bool exists(std::string const &parameterName) const
checks if a parameter exists
const double muonMass
double compCaloEnECAL(const reco::Candidate::LorentzVector &, const PFView &)
void compPFIso_raw(const reco::Candidate::LorentzVector &, const PFView &, const reco::Candidate::LorentzVector &, const reco::Candidate::LorentzVector &, double &, double &, double &)
edm::InputTag srcSelectedMuons_
edm::InputTag srcPFCandsNoPU_
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:433
virtual bool hasMasterClone() const =0
const_iterator begin() const
virtual double theta() const =0
momentum polar angle
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:120
double p4[4]
Definition: TauolaWrapper.h:92
double compPFIso_puCorr(const reco::Candidate::LorentzVector &, const PFView &, const PFView &, const reco::Candidate::LorentzVector &, const reco::Candidate::LorentzVector &)
T Abs(T a)
Definition: MathUtil.h:49
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:244
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:420
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:450
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
virtual bool hasMasterClonePtr() const =0
T Max(T a, T b)
Definition: MathUtil.h:44
bool isNull() const
Checks for null.
Definition: RefToBase.h:321
const double nomMassZ
bool filter(edm::Event &, const edm::EventSetup &)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:85
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:471
tuple cout
Definition: gather_cfg.py:121
const_iterator end() const
std::vector< reco::CandidateBaseRef > getSelMuons(const edm::Event &, const edm::InputTag &)
edm::InputTag srcPFCandsPU_
reco::CandidateBaseRef getTheMuPlus(const std::vector< reco::CandidateBaseRef > &)
virtual double phi() const =0
momentum azimuthal angle
virtual double eta() const =0
momentum pseudorapidity
MuonRadiationFilter(const edm::ParameterSet &)
virtual TrackRef globalTrack() const
reference to Track reconstructed in both tracked and muon detector
Definition: Muon.h:54
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
virtual const CandidateBaseRef & masterClone() const =0