CMS 3D CMS Logo

MuonCocktails.cc
Go to the documentation of this file.
1 #include "TMath.h"
4 
5 //
6 // Return the TeV-optimized refit track (aka the cocktail or Tune P) or
7 // the tracker track if either the optimized pT or tracker pT is below the pT threshold
8 //
10  const reco::TrackRef& trackerTrack,
11  const reco::TrackRef& tpfmsTrack,
12  const reco::TrackRef& pickyTrack,
13  const reco::TrackRef& dytTrack,
14  const double ptThreshold,
15  const double tune1,
16  const double tune2,
17  double dptcut) {
18  const unsigned int nAlgo=5;
19 
20  // Array for convenience below.
21  const reco::Muon::MuonTrackTypePair refit[nAlgo] = {
22  make_pair(trackerTrack, reco::Muon::InnerTrack),
23  make_pair(combinedTrack,reco::Muon::CombinedTrack),
24  make_pair(tpfmsTrack, reco::Muon::TPFMS),
25  make_pair(pickyTrack, reco::Muon::Picky),
26  make_pair(dytTrack, reco::Muon::DYT)
27  };
28 
29  // Calculate the log(tail probabilities). If there's a problem,
30  // signify this with prob == 0. The current problems recognized are:
31  // the track being not available, whether the (re)fit failed or it's
32  // just not in the event, or if the (re)fit ended up with no valid
33  // hits.
34  double prob[nAlgo] = {0.,0.,0.,0.,0.};
35  bool valid[nAlgo] = {false,false,false,false,false};
36 
37  double dptmin = 1.;
38 
39  if (dptcut>0) {
40  for (unsigned int i = 0; i < nAlgo; ++i)
41  if (refit[i].first.isNonnull())
42  if (refit[i].first->ptError()/refit[i].first->pt()<dptmin) dptmin = refit[i].first->ptError()/refit[i].first->pt();
43 
44  if (dptmin>dptcut) dptcut = dptmin+0.15;
45  }
46 
47  for (unsigned int i = 0; i < nAlgo; ++i)
48  if (refit[i].first.isNonnull()){
49  valid[i] = true;
50  if (refit[i].first->numberOfValidHits() && (refit[i].first->ptError()/refit[i].first->pt()<dptcut || dptcut<0))
51  prob[i] = muon::trackProbability(refit[i].first);
52  }
53 
54 
55  // Start with picky.
56  int chosen = 3;
57 
58  // If there's a problem with picky, make the default one of the
59  // other tracks. Try TPFMS first, then global, then tracker-only.
60  if (prob[3] == 0.) {
61 
62  // split so that passing dptcut<0 recreates EXACTLY the old tuneP behavior
63  if (dptcut>0) {
64  if (prob[4] > 0.) chosen = 4;
65  else if (prob[0] > 0.) chosen = 0;
66  else if (prob[2] > 0.) chosen = 2;
67  else if (prob[1] > 0.) chosen = 1;
68  } else {
69  if (prob[2] > 0.) chosen = 2;
70  else if (prob[1] > 0.) chosen = 1;
71  else if (prob[0] > 0.) chosen = 0;
72  }
73  }
74 
75  // Now the algorithm: switch from picky to dyt if the difference is lower than a tuned value. Then
76  // switch from picky to tracker-only if the
77  // difference, log(tail prob(picky)) - log(tail prob(tracker-only))
78  // is greater than a tuned value. Then compare the
79  // so-picked track to TPFMS in the same manner using another tuned
80  // value.
81  if (prob[4]>0. && prob[3]>0.) {
82  if(refit[3].first->pt()>0 && refit[4].first->pt()>0 &&
83  (refit[4].first->ptError()/refit[4].first->pt()-refit[3].first->ptError()/refit[3].first->pt())<=0)
84  chosen=4; // dyt
85  }
86 
87  if (prob[0] > 0. && prob[chosen] > 0. && (prob[chosen] - prob[0]) > tune1)
88  chosen = 0;
89  if (prob[2] > 0. && (prob[chosen] - prob[2]) > tune2)
90  chosen = 2;
91 
92  // Sanity checks
93  if (chosen == 4 && !valid[4] ) chosen = 3;
94  if (chosen == 3 && !valid[3] ) chosen = 2;
95  if (chosen == 2 && !valid[2] ) chosen = 1;
96  if (chosen == 1 && !valid[1] ) chosen = 0;
97 
98  // Done. If pT of the chosen track (or pT of the tracker track) is below the threshold value, return the tracker track.
99  if (valid[chosen] && refit[chosen].first->pt() < ptThreshold && prob[0] > 0.) return make_pair(trackerTrack,reco::Muon::InnerTrack);
100  if (trackerTrack->pt() < ptThreshold && prob[0] > 0.) return make_pair(trackerTrack,reco::Muon::InnerTrack);
101 
102  // Return the chosen track (which can be the global track in
103  // very rare cases).
104  return refit[chosen];
105 }
106 
107 //
108 // calculate the tail probability (-ln(P)) of a fit
109 //
111 
112  int nDOF = (int)track->ndof();
113  if ( nDOF > 0 && track->chi2()> 0) {
114  return -log(TMath::Prob(track->chi2(), nDOF));
115  } else {
116  return 0.0;
117  }
118 
119 }
120 
122  const reco::TrackToTrackMap& map) {
123  reco::TrackToTrackMap::const_iterator it = map.find(combinedTrack);
124  return it == map.end() ? reco::TrackRef() : it->val;
125 }
126 
127 
128 //
129 // Get the sigma-switch decision (tracker-only versus global).
130 //
132  const reco::TrackRef& trackerTrack,
133  const double nSigma,
134  const double ptThreshold) {
135  // If either the global or tracker-only fits have pT below threshold
136  // (default 200 GeV), return the tracker-only fit.
137  if (combinedTrack->pt() < ptThreshold || trackerTrack->pt() < ptThreshold)
138  return make_pair(trackerTrack,reco::Muon::InnerTrack);
139 
140  // If both are above the pT threshold, compare the difference in
141  // q/p: if less than two sigma of the tracker-only track, switch to
142  // global. Otherwise, use tracker-only.
143  const double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
144  const double threshold = nSigma * trackerTrack->qoverpError();
145  return delta > threshold ? make_pair(trackerTrack,reco::Muon::InnerTrack) : make_pair(combinedTrack,reco::Muon::CombinedTrack);
146 }
147 
148 //
149 // Get the TMR decision (tracker-only versus TPFMS).
150 //
152  const reco::TrackRef& fmsTrack,
153  const double tune) {
154  double probTK = 0;
155  double probFMS = 0;
156 
157  if (trackerTrack.isNonnull() && trackerTrack->numberOfValidHits())
158  probTK = muon::trackProbability(trackerTrack);
159  if (fmsTrack.isNonnull() && fmsTrack->numberOfValidHits())
160  probFMS = muon::trackProbability(fmsTrack);
161 
162  bool TKok = probTK > 0;
163  bool FMSok = probFMS > 0;
164 
165  if (TKok && FMSok) {
166  if (probFMS - probTK > tune)
167  return make_pair(trackerTrack,reco::Muon::InnerTrack);
168  else
169  return make_pair(fmsTrack,reco::Muon::TPFMS);
170  }
171  else if (FMSok)
172  return make_pair(fmsTrack,reco::Muon::TPFMS);
173  else if (TKok)
174  return make_pair(trackerTrack,reco::Muon::InnerTrack);
175  else
176  return make_pair(reco::TrackRef(),reco::Muon::None);
177 }
dbl * delta
Definition: mlp_gen.cc:36
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
const_iterator end() const
last iterator over the map (read only)
const_iterator find(const key_type &k) const
find element with specified reference key
reco::Muon::MuonTrackTypePair sigmaSwitch(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const double nSigma=2., const double ptThreshold=200.)
reco::Muon::MuonTrackTypePair tevOptimized(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const reco::TrackRef &tpfmsTrack, const reco::TrackRef &pickyTrack, const reco::TrackRef &dytTrack, const double ptThreshold=200., const double tune1=17., const double tune2=40., const double dptcut=0.25)
Definition: MuonCocktails.cc:9
reco::Muon::MuonTrackTypePair TMR(const reco::TrackRef &trackerTrack, const reco::TrackRef &fmsTrack, const double tune=4.)
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:21
reco::TrackRef getTevRefitTrack(const reco::TrackRef &combinedTrack, const reco::TrackToTrackMap &map)
double trackProbability(const reco::TrackRef track)
std::pair< TrackRef, Muon::MuonTrackType > MuonTrackTypePair
Definition: Muon.h:40