CMS 3D CMS Logo

MuonTCMETValueMapProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: METProducers
4 // Class: MuonTCMETValueMapProducer
5 //
6 // Original Author: Frank Golf
7 // Created: Sun Mar 15 11:33:20 CDT 2009
8 //
9 //
10 
11 //____________________________________________________________________________||
13 
15 
28 
31 
34 
35 #include "TVector3.h"
36 #include "TMath.h"
37 
38 #include <algorithm>
39 
40 //____________________________________________________________________________||
42 
43 //____________________________________________________________________________||
44 namespace cms {
45 
47  produces<edm::ValueMap<reco::MuonMETCorrectionData>>("muCorrData");
48 
49  rfType_ = iConfig.getParameter<int>("rf_type");
50 
51  nLayers_ = iConfig.getParameter<int>("nLayers");
52  nLayersTight_ = iConfig.getParameter<int>("nLayersTight");
53  vertexNdof_ = iConfig.getParameter<int>("vertexNdof");
54  vertexZ_ = iConfig.getParameter<double>("vertexZ");
55  vertexRho_ = iConfig.getParameter<double>("vertexRho");
56  vertexMaxDZ_ = iConfig.getParameter<double>("vertexMaxDZ");
57  maxpt_eta20_ = iConfig.getParameter<double>("maxpt_eta20");
58  maxpt_eta25_ = iConfig.getParameter<double>("maxpt_eta25");
59 
60  // get configuration parameters
61  std::vector<std::string> algos = iConfig.getParameter<std::vector<std::string>>("trackAlgos");
62  std::transform(algos.begin(), algos.end(), std::back_inserter(trkAlgos_), [](const std::string& a) {
64  });
65  maxd0cut_ = iConfig.getParameter<double>("d0_max");
66  minpt_ = iConfig.getParameter<double>("pt_min");
67  maxpt_ = iConfig.getParameter<double>("pt_max");
68  maxeta_ = iConfig.getParameter<double>("eta_max");
69  maxchi2_ = iConfig.getParameter<double>("chi2_max");
70  minhits_ = iConfig.getParameter<double>("nhits_min");
71  maxPtErr_ = iConfig.getParameter<double>("ptErr_max");
72 
73  trkQuality_ = iConfig.getParameter<std::vector<int>>("track_quality");
74  algos = iConfig.getParameter<std::vector<std::string>>("track_algos");
75  std::transform(algos.begin(), algos.end(), std::back_inserter(trkAlgos_), [](const std::string& a) {
77  });
78  maxchi2_tight_ = iConfig.getParameter<double>("chi2_max_tight");
79  minhits_tight_ = iConfig.getParameter<double>("nhits_min_tight");
80  maxPtErr_tight_ = iConfig.getParameter<double>("ptErr_max_tight");
81  usePvtxd0_ = iConfig.getParameter<bool>("usePvtxd0");
82  d0cuta_ = iConfig.getParameter<double>("d0cuta");
83  d0cutb_ = iConfig.getParameter<double>("d0cutb");
84 
85  muon_dptrel_ = iConfig.getParameter<double>("muon_dptrel");
86  muond0_ = iConfig.getParameter<double>("d0_muon");
87  muonpt_ = iConfig.getParameter<double>("pt_muon");
88  muoneta_ = iConfig.getParameter<double>("eta_muon");
89  muonchi2_ = iConfig.getParameter<double>("chi2_muon");
90  muonhits_ = iConfig.getParameter<double>("nhits_muon");
91  muonGlobal_ = iConfig.getParameter<bool>("global_muon");
92  muonTracker_ = iConfig.getParameter<bool>("tracker_muon");
93  muonDeltaR_ = iConfig.getParameter<double>("deltaR_muon");
94  useCaloMuons_ = iConfig.getParameter<bool>("useCaloMuons");
95  muonMinValidStaHits_ = iConfig.getParameter<int>("muonMinValidStaHits");
96 
97  response_function = nullptr;
98  tcmetAlgo_ = new TCMETAlgo();
99 
100  if (rfType_ == 1)
102  else if (rfType_ == 2)
104 
105  muonToken_ = consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("muonInputTag"));
106  beamSpotToken_ = consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamSpotInputTag"));
107  vertexToken_ = consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexInputTag"));
108  magFieldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>();
109  }
110 
111  //____________________________________________________________________________||
113 
114  //____________________________________________________________________________||
116  iEvent.getByToken(muonToken_, muons_);
117  iEvent.getByToken(beamSpotToken_, beamSpot_);
118 
119  hasValidVertex = false;
120  if (usePvtxd0_) {
121  iEvent.getByToken(vertexToken_, vertexHandle_);
122 
123  if (vertexHandle_.isValid()) {
126  }
127  }
128 
130  bField = theMagField.product();
131 
132  auto vm_muCorrData = std::make_unique<edm::ValueMap<reco::MuonMETCorrectionData>>();
133 
134  std::vector<reco::MuonMETCorrectionData> v_muCorrData;
135 
136  unsigned int nMuons = muons_->size();
137 
138  for (unsigned int iMu = 0; iMu < nMuons; iMu++) {
139  const reco::Muon* mu = &(*muons_)[iMu];
140  double deltax = 0.0;
141  double deltay = 0.0;
142 
144 
145  reco::TrackRef mu_track;
146  if (mu->isGlobalMuon() || mu->isTrackerMuon() || mu->isCaloMuon())
147  mu_track = mu->innerTrack();
148  else {
149  v_muCorrData.push_back(muMETCorrData);
150  continue;
151  }
152 
153  // figure out depositions muons would make if they were treated as pions
154  if (isGoodTrack(mu)) {
155  if (mu_track->pt() < minpt_)
157 
158  else {
159  int bin_index = response_function->FindBin(mu_track->eta(), mu_track->pt());
160  double response = response_function->GetBinContent(bin_index);
161 
162  TVector3 outerTrkPosition = propagateTrack(mu);
163 
164  deltax = response * mu_track->p() * sin(outerTrkPosition.Theta()) * cos(outerTrkPosition.Phi());
165  deltay = response * mu_track->p() * sin(outerTrkPosition.Theta()) * sin(outerTrkPosition.Phi());
166 
168  }
169  }
170 
171  // figure out muon flag
172  if (isGoodMuon(mu))
173  v_muCorrData.push_back(
175 
176  else if (useCaloMuons_ && isGoodCaloMuon(mu, iMu))
177  v_muCorrData.push_back(
179 
180  else
181  v_muCorrData.push_back(muMETCorrData);
182  }
183 
184  edm::ValueMap<reco::MuonMETCorrectionData>::Filler dataFiller(*vm_muCorrData);
185 
186  dataFiller.insert(muons_, v_muCorrData.begin(), v_muCorrData.end());
187  dataFiller.fill();
188 
189  iEvent.put(std::move(vm_muCorrData), "muCorrData");
190  }
191 
192  //____________________________________________________________________________||
194  double d0 = -999;
195  double nhits = 0;
196  double chi2 = 999;
197 
198  // get d0 corrected for beam spot
199  bool haveBeamSpot = true;
200  if (!beamSpot_.isValid())
201  haveBeamSpot = false;
202 
203  if (muonGlobal_ && !muon->isGlobalMuon())
204  return false;
205  if (muonTracker_ && !muon->isTrackerMuon())
206  return false;
207 
208  const reco::TrackRef siTrack = muon->innerTrack();
209  const reco::TrackRef globalTrack = muon->globalTrack();
210 
211  Point bspot = haveBeamSpot ? beamSpot_->position() : Point(0, 0, 0);
212  if (siTrack.isNonnull())
213  nhits = siTrack->numberOfValidHits();
214  if (globalTrack.isNonnull()) {
215  d0 = -1 * globalTrack->dxy(bspot);
216  chi2 = globalTrack->normalizedChi2();
217  }
218 
219  if (fabs(d0) > muond0_)
220  return false;
221  if (muon->pt() < muonpt_)
222  return false;
223  if (fabs(muon->eta()) > muoneta_)
224  return false;
225  if (nhits < muonhits_)
226  return false;
227  if (chi2 > muonchi2_)
228  return false;
229  if (globalTrack->hitPattern().numberOfValidMuonHits() < muonMinValidStaHits_)
230  return false;
231 
232  //reject muons with tracker dpt/pt > X
233  if (!siTrack.isNonnull())
234  return false;
235  if (siTrack->ptError() / siTrack->pt() > muon_dptrel_)
236  return false;
237 
238  else
239  return true;
240  }
241 
242  //____________________________________________________________________________||
244  if (muon->pt() < 10)
245  return false;
246 
247  if (!isGoodTrack(muon))
248  return false;
249 
250  const reco::TrackRef inputSiliconTrack = muon->innerTrack();
251  if (!inputSiliconTrack.isNonnull())
252  return false;
253 
254  //check if it is in the vicinity of a global or tracker muon
255  unsigned int nMuons = muons_->size();
256  for (unsigned int iMu = 0; iMu < nMuons; iMu++) {
257  if (iMu == index)
258  continue;
259 
260  const reco::Muon* mu = &(*muons_)[iMu];
261 
262  const reco::TrackRef testSiliconTrack = mu->innerTrack();
263  if (!testSiliconTrack.isNonnull())
264  continue;
265 
266  double deltaEta = inputSiliconTrack.get()->eta() - testSiliconTrack.get()->eta();
267  double deltaPhi = acos(cos(inputSiliconTrack.get()->phi() - testSiliconTrack.get()->phi()));
268  double deltaR = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi);
269 
270  if (deltaR < muonDeltaR_)
271  return false;
272  }
273 
274  return true;
275  }
276 
277  //____________________________________________________________________________||
279  double d0;
280 
281  const reco::TrackRef siTrack = muon->innerTrack();
282  if (!siTrack.isNonnull())
283  return false;
284 
285  if (hasValidVertex) {
286  //get d0 corrected for primary vertex
287 
288  const Point pvtx = Point(vertices_->begin()->x(), vertices_->begin()->y(), vertices_->begin()->z());
289 
290  double dz = siTrack->dz(pvtx);
291 
292  if (fabs(dz) < vertexMaxDZ_) {
293  //get d0 corrected for pvtx
294  d0 = -1 * siTrack->dxy(pvtx);
295 
296  } else {
297  // get d0 corrected for beam spot
298  bool haveBeamSpot = true;
299  if (!beamSpot_.isValid())
300  haveBeamSpot = false;
301 
302  Point bspot = haveBeamSpot ? beamSpot_->position() : Point(0, 0, 0);
303  d0 = -1 * siTrack->dxy(bspot);
304  }
305  } else {
306  // get d0 corrected for beam spot
307  bool haveBeamSpot = true;
308  if (!beamSpot_.isValid())
309  haveBeamSpot = false;
310 
311  Point bspot = haveBeamSpot ? beamSpot_->position() : Point(0, 0, 0);
312  d0 = -1 * siTrack->dxy(bspot);
313  }
314 
315  if (std::find(trackAlgos_.begin(), trackAlgos_.end(), siTrack->algo()) != trackAlgos_.end()) {
316  //1st 4 tracking iterations (pT-dependent d0 cut)
317 
318  float d0cut = sqrt(std::pow(d0cuta_, 2) + std::pow(d0cutb_ / siTrack->pt(), 2));
319  if (d0cut > maxd0cut_)
320  d0cut = maxd0cut_;
321 
322  if (fabs(d0) > d0cut)
323  return false;
324  if (nLayers(siTrack) < nLayers_)
325  return false;
326  } else {
327  //last 2 tracking iterations (tighten chi2, nhits, pt error cuts)
328 
329  if (siTrack->normalizedChi2() > maxchi2_tight_)
330  return false;
331  if (siTrack->numberOfValidHits() < minhits_tight_)
332  return false;
333  if ((siTrack->ptError() / siTrack->pt()) > maxPtErr_tight_)
334  return false;
335  if (nLayers(siTrack) < nLayersTight_)
336  return false;
337  }
338 
339  if (siTrack->numberOfValidHits() < minhits_)
340  return false;
341  if (siTrack->normalizedChi2() > maxchi2_)
342  return false;
343  if (fabs(siTrack->eta()) > maxeta_)
344  return false;
345  if (siTrack->pt() > maxpt_)
346  return false;
347  if ((siTrack->ptError() / siTrack->pt()) > maxPtErr_)
348  return false;
349  if (fabs(siTrack->eta()) > 2.5 && siTrack->pt() > maxpt_eta25_)
350  return false;
351  if (fabs(siTrack->eta()) > 2.0 && siTrack->pt() > maxpt_eta20_)
352  return false;
353 
354  int cut = 0;
355  for (unsigned int i = 0; i < trkQuality_.size(); i++) {
356  cut |= (1 << trkQuality_.at(i));
357  }
358 
359  if (!((siTrack->qualityMask() & cut) == cut))
360  return false;
361 
362  bool isGoodAlgo = false;
363  if (trkAlgos_.empty())
364  isGoodAlgo = true;
365  for (unsigned int i = 0; i < trkAlgos_.size(); i++) {
366  if (siTrack->algo() == trkAlgos_.at(i))
367  isGoodAlgo = true;
368  }
369 
370  if (!isGoodAlgo)
371  return false;
372 
373  return true;
374  }
375 
376  //____________________________________________________________________________||
378  TVector3 outerTrkPosition;
379 
380  outerTrkPosition.SetPtEtaPhi(999., -10., 2 * TMath::Pi());
381 
382  const reco::TrackRef track = muon->innerTrack();
383 
384  if (!track.isNonnull()) {
385  return outerTrkPosition;
386  }
387 
388  GlobalPoint tpVertex(track->vx(), track->vy(), track->vz());
389  GlobalVector tpMomentum(track.get()->px(), track.get()->py(), track.get()->pz());
390  int tpCharge(track->charge());
391 
392  FreeTrajectoryState fts(tpVertex, tpMomentum, tpCharge, bField);
393 
394  const double zdist = 314.;
395 
396  const double radius = 130.;
397 
398  const double corner = 1.479;
399 
402 
405 
407 
409 
410  if (track.get()->eta() < -corner) {
411  tsos = myAP.propagate(fts, *lendcap);
412  } else if (fabs(track.get()->eta()) < corner) {
413  tsos = myAP.propagate(fts, *barrel);
414  } else if (track.get()->eta() > corner) {
415  tsos = myAP.propagate(fts, *rendcap);
416  }
417 
418  if (tsos.isValid())
419  outerTrkPosition.SetXYZ(tsos.globalPosition().x(), tsos.globalPosition().y(), tsos.globalPosition().z());
420 
421  else
422  outerTrkPosition.SetPtEtaPhi(999., -10., 2 * TMath::Pi());
423 
424  return outerTrkPosition;
425  }
426 
427  //____________________________________________________________________________||
429  const reco::HitPattern& p = track->hitPattern();
430  return p.trackerLayersWithMeasurement();
431  }
432 
433  //____________________________________________________________________________||
435  if (vertices_->begin()->isFake())
436  return false;
437  if (vertices_->begin()->ndof() < vertexNdof_)
438  return false;
439  if (fabs(vertices_->begin()->z()) > vertexZ_)
440  return false;
441  if (sqrt(std::pow(vertices_->begin()->x(), 2) + std::pow(vertices_->begin()->y(), 2)) > vertexRho_)
442  return false;
443 
444  return true;
445  }
446 
447 } // namespace cms
448 
449 //____________________________________________________________________________||
class TVector3 propagateTrack(const reco::Muon *)
const double Pi
edm::Handle< reco::VertexCollection > vertexHandle_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
MuonTCMETValueMapProducer(const edm::ParameterSet &)
TH2D * getResponseFunction_fit()
Definition: TCMETAlgo.cc:3523
std::vector< reco::TrackBase::TrackAlgorithm > trackAlgos_
const Point & position() const
position
Definition: BeamSpot.h:59
T z() const
Definition: PV3DBase.h:61
edm::EDGetTokenT< reco::VertexCollection > vertexToken_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const reco::VertexCollection * vertices_
T const * product() const
Definition: Handle.h:70
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
void produce(edm::Event &, const edm::EventSetup &) override
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const class MagneticField * bField
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
bool isGoodCaloMuon(const reco::Muon *, const unsigned int)
static const double deltaEta
Definition: CaloConstants.h:8
static PlanePointer build(Args &&... args)
Definition: Plane.h:33
std::vector< reco::TrackBase::TrackAlgorithm > trkAlgos_
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
int iEvent
Definition: GenABIO.cc:224
T const * product() const
Definition: ESHandle.h:86
GlobalPoint globalPosition() const
T sqrt(T t)
Definition: SSEVec.h:23
edm::EDGetTokenT< reco::BeamSpot > beamSpotToken_
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
edm::Handle< reco::MuonCollection > muons_
TH2D * getResponseFunction_mode()
Definition: TCMETAlgo.cc:4995
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
#define M_PI
Namespace of DDCMS conversion namespace.
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magFieldToken_
math::XYZPoint Point
static constexpr float d0
static CylinderPointer build(const PositionType &pos, const RotationType &rot, Scalar radius, Bounds *bounds=nullptr)
Definition: Cylinder.h:45
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
edm::Handle< reco::BeamSpot > beamSpot_
bool isValid() const
Definition: HandleBase.h:70
Structure Point Contains parameters of Gaussian fits to DMRs.
double a
Definition: hdecay.h:121
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
static TrackAlgorithm algoByName(const std::string &name)
Definition: TrackBase.cc:137
edm::EDGetTokenT< reco::MuonCollection > muonToken_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
unsigned transform(const HcalDetId &id, unsigned transformCode)