CMS 3D CMS Logo

DistortedPFCandProducer.cc
Go to the documentation of this file.
1 #include <memory>
5 
10 
13 
14 //
15 // class declaration
16 //
18  public:
20  ~DistortedPFCandProducer() override;
21 
22  private:
23  void beginJob() override ;
24  void produce(edm::Event&, const edm::EventSetup&) override;
25  void endJob() override ;
26 
30  std::vector<double> etaBinEdges_;
31 
32  std::vector<double> shiftOnOneOverPt_; // in [1/GeV]
33  std::vector<double> relativeShiftOnPt_;
34  std::vector<double> uncertaintyOnOneOverPt_; // in [1/GeV]
35  std::vector<double> relativeUncertaintyOnPt_;
36 
37  std::vector<double> efficiencyRatioOverMC_;
38 };
39 
46 
47 #include <CLHEP/Random/RandFlat.h>
48 #include <CLHEP/Random/RandGauss.h>
49 
52 
53  // What is being produced
54  produces<std::vector<reco::PFCandidate> >();
55 
56  // Input products
57  muonToken_ = consumes<edm::View<reco::Muon> >(pset.getUntrackedParameter<edm::InputTag> ("MuonTag", edm::InputTag("muons")));
58  genMatchMapToken_ = consumes<reco::GenParticleMatch>(pset.getUntrackedParameter<edm::InputTag> ("GenMatchMapTag", edm::InputTag("genMatchMap")));
59  pfToken_ = consumes<edm::View<reco::PFCandidate> >(pset.getUntrackedParameter<edm::InputTag> ("PFTag", edm::InputTag("particleFlow")));
60 
61  // Eta edges
62  std::vector<double> defEtaEdges;
63  defEtaEdges.push_back(-999999.);
64  defEtaEdges.push_back(999999.);
65  etaBinEdges_ = pset.getUntrackedParameter<std::vector<double> > ("EtaBinEdges",defEtaEdges);
66  unsigned int ninputs_expected = etaBinEdges_.size()-1;
67 
68  // Distortions in muon momentum
69  std::vector<double> defDistortion;
70  defDistortion.push_back(0.);
71 
72  shiftOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("ShiftOnOneOverPt",defDistortion); // in [1/GeV]
73  if (shiftOnOneOverPt_.size()==1 && ninputs_expected>1) {
74  for (unsigned int i=1; i<ninputs_expected; i++){ shiftOnOneOverPt_.push_back(shiftOnOneOverPt_[0]);}
75  }
76 
77  relativeShiftOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeShiftOnPt",defDistortion);
78  if (relativeShiftOnPt_.size()==1 && ninputs_expected>1) {
79  for (unsigned int i=1; i<ninputs_expected; i++){ relativeShiftOnPt_.push_back(relativeShiftOnPt_[0]);}
80  }
81 
82  uncertaintyOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("UncertaintyOnOneOverPt",defDistortion); // in [1/GeV]
83  if (uncertaintyOnOneOverPt_.size()==1 && ninputs_expected>1) {
84  for (unsigned int i=1; i<ninputs_expected; i++){ uncertaintyOnOneOverPt_.push_back(uncertaintyOnOneOverPt_[0]);}
85  }
86 
87  relativeUncertaintyOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeUncertaintyOnPt",defDistortion);
88  if (relativeUncertaintyOnPt_.size()==1 && ninputs_expected>1) {
89  for (unsigned int i=1; i<ninputs_expected; i++){ relativeUncertaintyOnPt_.push_back(relativeUncertaintyOnPt_[0]);}
90  }
91 
92  // Data/MC efficiency ratios
93  std::vector<double> defEfficiencyRatio;
94  defEfficiencyRatio.push_back(1.);
95  efficiencyRatioOverMC_ = pset.getUntrackedParameter<std::vector<double> > ("EfficiencyRatioOverMC",defEfficiencyRatio);
96  if (efficiencyRatioOverMC_.size()==1 && ninputs_expected>1) {
97  for (unsigned int i=1; i<ninputs_expected; i++){ efficiencyRatioOverMC_.push_back(efficiencyRatioOverMC_[0]);}
98  }
99 
100  // Send a warning if there are inconsistencies in vector sizes !!
101  bool effWrong = efficiencyRatioOverMC_.size()!=ninputs_expected;
102  bool momWrong = shiftOnOneOverPt_.size()!=ninputs_expected
103  || relativeShiftOnPt_.size()!=ninputs_expected
104  || uncertaintyOnOneOverPt_.size()!=ninputs_expected
105  || relativeUncertaintyOnPt_.size()!=ninputs_expected;
106  if ( effWrong and momWrong) {
107  edm::LogError("") << "WARNING: DistortedPFCandProducer : Size of some parameters do not match the EtaBinEdges vector!!";
108  }
109 
110 }
111 
114 }
115 
118 }
119 
122 }
123 
126 
127  if (ev.isRealData()) return;
128 
129  // Muon collection
131  if (!ev.getByToken(muonToken_, muonCollection)) {
132  edm::LogError("") << ">>> Muon collection does not exist !!!";
133  return;
134  }
135 
137  if (!ev.getByToken(genMatchMapToken_, genMatchMap)) {
138  edm::LogError("") << ">>> Muon-GenParticle match map does not exist !!!";
139  return;
140  }
141 
142 
143  // Get PFCandidate collection
145  if (!ev.getByToken(pfToken_, pfCollection)) {
146  edm::LogError("") << ">>> PFCandidate collection does not exist !!!";
147  return;
148  }
149 
150  unsigned int muonCollectionSize = muonCollection->size();
151  unsigned int pfCollectionSize = pfCollection->size();
152 
153  if (pfCollectionSize<1) return;
154 
155 
156  // Ask for PfMuon consistency
157  bool pfMuonFound = false;
158 
159 
160 
161  std::unique_ptr<reco::PFCandidateCollection> newmuons (new reco::PFCandidateCollection);
162 
163 
164  // Loop on all PF candidates
165  for (unsigned int j=0; j<pfCollectionSize; j++) {
166  edm::RefToBase<reco::PFCandidate> pf = pfCollection->refAt(j);
167 
168 
169  // New PF muon
170  double ptmu = pf->pt();
171 
172 
173  for (unsigned int i=0; i<muonCollectionSize; i++) {
174  edm::RefToBase<reco::Muon> mu = muonCollection->refAt(i);
175 
176 
177  // Check the muon is in the PF collection
178  if (pf->particleId()==reco::PFCandidate::mu) {
179  reco::MuonRef muref = pf->muonRef();
180  if (muref.isNonnull()) {
181  if (muref.key()==mu.key()) {
182  if ( mu->isStandAloneMuon() && ptmu == muref->standAloneMuon()->pt() && (
183  ( !mu->isGlobalMuon() || ( mu->isGlobalMuon() && ptmu != muref->combinedMuon()->pt() ) ) &&
184  ( !mu->isTrackerMuon() || ( mu->isTrackerMuon() && ptmu != mu->track()->pt() ) ) )
185  ) {
186  pfMuonFound = false;
187  }
188  else if ( !mu->isTrackerMuon() ){
189  pfMuonFound = false;
190  }
191  else{
192  pfMuonFound = true;}
193  }
194  else {pfMuonFound = false; }
195 
196  }
197  }
198 
199  // do nothing if StandAlone muon
200  //const reco::Track& track = *trackRef;
201 
202  if ( !pfMuonFound) continue;
203 
204  double ptgen = pf->pt();
205  double etagen = pf->eta();
206 
207 
208  reco::GenParticleRef gen = (*genMatchMap)[mu];
209  if( !gen.isNull()) {
210  ptgen = gen->pt();
211  etagen = gen->eta();
212  LogTrace("") << ">>> Muon-GenParticle match found; ptmu= " << pf->pt() << ", ptgen= " << ptgen;
213  } else {
214  LogTrace("") << ">>> MUON-GENPARTICLE MATCH NOT FOUND!!!";
215  }
216 
217 
218  // Initialize parameters
219  double effRatio = 0.;
220  double shift1 = 0.;
221  double shift2 = 0.;
222  double sigma1 = 0.;
223  double sigma2 = 0.;
224 
225  // Find out which eta bin should be used
226  unsigned int nbins = etaBinEdges_.size()-1;
227  unsigned int etaBin = nbins;
228  if (etagen>etaBinEdges_[0] && etagen<etaBinEdges_[nbins]) {
229  for (unsigned int j=1; j<=nbins; ++j) {
230  if (etagen>etaBinEdges_[j]) continue;
231  etaBin = j-1;
232  break;
233  }
234  }
235  if (etaBin<nbins) {
236  LogTrace("") << ">>> etaBin: " << etaBin << ", for etagen =" << etagen;
237  } else {
238  // Muon is rejected if outside the considered eta range
239  LogTrace("") << ">>> Muon outside eta range: reject it; etagen = " << etagen;
240  pfMuonFound = false;
241  continue;
242  }
243 
244  if (!pfMuonFound) continue;
245 
246  // Set shifts
247  shift1 = shiftOnOneOverPt_[etaBin];
248  shift2 = relativeShiftOnPt_[etaBin];
249  LogTrace("") << "\tshiftOnOneOverPt= " << shift1*100 << " [%]";
250  LogTrace("") << "\trelativeShiftOnPt= " << shift2*100 << " [%]";
251 
252  // Set resolutions
255  LogTrace("") << "\tuncertaintyOnOneOverPt= " << sigma1 << " [1/GeV]";
256  LogTrace("") << "\trelativeUncertaintyOnPt= " << sigma2*100 << " [%]";
257 
258  // Set efficiency ratio
259  effRatio = efficiencyRatioOverMC_[etaBin];
260  LogTrace("") << "\tefficiencyRatioOverMC= " << effRatio;
261 
262  // Reject muons according to efficiency ratio
263  double rndf = CLHEP::RandFlat::shoot();
264  if (rndf>effRatio) continue;
265 
266  // Gaussian Random numbers for smearing
267  double rndg1 = CLHEP::RandGauss::shoot();
268  double rndg2 = CLHEP::RandGauss::shoot();
269 
270 
271  // change here the pt of the candidate, if it is a muon
272 
273  ptmu += ptgen * ( shift1*ptgen + shift2 + sigma1*rndg1*ptgen + sigma2*rndg2);
274  pfMuonFound = false ;
275 
276  }
277 
278  reco::PFCandidate* newmu = pf->clone();
279  newmu->setP4 (
281  ptmu, pf->eta(), pf->phi(), pf->mass()
282  )
283  );
284 
285  newmuons->push_back(*newmu);
286  }
287 
288 
289  ev.put(std::move(newmuons));
290 
291 
292 }
293 
T getUntrackedParameter(std::string const &, T const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
TrackRef track() const override
reference to a Track
Definition: Muon.h:49
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
double eta() const final
momentum pseudorapidity
bool isStandAloneMuon() const override
Definition: Muon.h:293
std::vector< double > relativeUncertaintyOnPt_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
edm::EDGetTokenT< edm::View< reco::PFCandidate > > pfToken_
double pt() const final
transverse momentum
bool ev
key_type key() const
Accessor for product key.
Definition: Ref.h:263
bool isRealData() const
Definition: EventBase.h:62
bool isTrackerMuon() const override
Definition: Muon.h:292
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< reco::GenParticleMatch > genMatchMapToken_
bool isGlobalMuon() const override
Definition: Muon.h:291
std::vector< double > uncertaintyOnOneOverPt_
size_t key() const
Definition: RefToBase.h:250
const int mu
Definition: Constants.h:22
bool isNull() const
Checks for null.
Definition: Ref.h:248
#define LogTrace(id)
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:459
PFCandidate * clone() const override
return a clone
Definition: PFCandidate.cc:215
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
edm::EDGetTokenT< edm::View< reco::Muon > > muonToken_
std::vector< double > efficiencyRatioOverMC_
void produce(edm::Event &, const edm::EventSetup &) override
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Particle.h:23
virtual ParticleType particleId() const
Definition: PFCandidate.h:374
std::vector< double > relativeShiftOnPt_
std::vector< double > shiftOnOneOverPt_
double phi() const final
momentum azimuthal angle
void setP4(const LorentzVector &p4) final
set 4-momentum
def move(src, dest)
Definition: eostools.py:511
std::vector< double > etaBinEdges_
double mass() const final
mass
DistortedPFCandProducer(const edm::ParameterSet &)