CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DataFormats/MuonReco/src/MuonCocktails.cc

Go to the documentation of this file.
00001 #include "TMath.h"
00002 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
00003 #include "DataFormats/TrackReco/interface/Track.h"
00004 
00005 //
00006 // Return the TeV-optimized refit track, aka the cocktail or Tune P.
00007 //
00008 reco::TrackRef muon::tevOptimized(const reco::TrackRef& combinedTrack,
00009                                   const reco::TrackRef& trackerTrack,
00010                                   const reco::TrackRef& tpfmsTrack,
00011                                   const reco::TrackRef& pickyTrack,
00012                                   const double tune1,
00013                                   const double tune2) {
00014   // Array for convenience below.
00015   const reco::TrackRef refit[4] = { 
00016     trackerTrack, 
00017     combinedTrack, 
00018     tpfmsTrack, 
00019     pickyTrack 
00020   }; 
00021 
00022   // Calculate the log(tail probabilities). If there's a problem,
00023   // signify this with prob == 0. The current problems recognized are:
00024   // the track being not available, whether the (re)fit failed or it's
00025   // just not in the event, or if the (re)fit ended up with no valid
00026   // hits.
00027   double prob[4] = {0.};
00028   for (unsigned int i = 0; i < 4; ++i) 
00029     if (refit[i].isNonnull() && refit[i]->numberOfValidHits()) 
00030       prob[i] = muon::trackProbability(refit[i]); 
00031 
00032   //std::cout << "Probabilities: " << prob[0] << " " << prob[1] << " " << prob[2] << " " << prob[3] << std::endl;
00033 
00034   // Start with picky.
00035   int chosen = 3;
00036 
00037   // If there's a problem with picky, make the default one of the
00038   // other tracks. Try TPFMS first, then global, then tracker-only.
00039   if (prob[3] == 0.) { 
00040     if      (prob[2] > 0.) chosen = 2;
00041     else if (prob[1] > 0.) chosen = 1;
00042     else if (prob[0] > 0.) chosen = 0;
00043   } 
00044 
00045   // Now the algorithm: switch from picky to tracker-only if the
00046   // difference, log(tail prob(picky)) - log(tail prob(tracker-only))
00047   // is greater than a tuned value (currently 30). Then compare the
00048   // so-picked track to TPFMS in the same manner using another tuned
00049   // value.
00050   if (prob[0] > 0. && prob[3] > 0. && (prob[3] - prob[0]) > tune1)
00051     chosen = 0;
00052   if (prob[2] > 0. && (prob[chosen] - prob[2]) > tune2)
00053     chosen = 2;
00054 
00055   // Done. Return the chosen track (which can be the global track in
00056   // very rare cases).
00057   return refit[chosen];
00058 }
00059 
00060 //
00061 // Return the TeV-optimized refit track (older, deprecated version).
00062 //
00063 reco::TrackRef muon::tevOptimizedOld( const reco::TrackRef& combinedTrack,
00064                                       const reco::TrackRef& trackerTrack,
00065                                       const reco::TrackToTrackMap tevMap1,
00066                                       const reco::TrackToTrackMap tevMap2,
00067                                       const reco::TrackToTrackMap tevMap3 ) {
00068 
00069   std::vector<reco::TrackRef> refit(4);
00070   reco::TrackRef result;
00071   bool ok[4];
00072   ok[0] = true; // Assume tracker track OK.
00073   
00074   reco::TrackToTrackMap::const_iterator gmrTrack = tevMap1.find(combinedTrack);
00075   reco::TrackToTrackMap::const_iterator fmsTrack = tevMap2.find(combinedTrack);
00076   reco::TrackToTrackMap::const_iterator pmrTrack = tevMap3.find(combinedTrack);
00077 
00078   ok[1] = gmrTrack != tevMap1.end();
00079   ok[2] = fmsTrack != tevMap2.end();
00080   ok[3] = pmrTrack != tevMap3.end();
00081 
00082   double prob[4];
00083 
00084   if (ok[0]) refit[0] = trackerTrack;
00085   if (ok[1]) refit[1] = (*gmrTrack).val;
00086   if (ok[2]) refit[2] = (*fmsTrack).val;
00087   if (ok[3]) refit[3] = (*pmrTrack).val;
00088   
00089   for (unsigned int i=0; i<4; i++)
00090     prob[i] = (ok[i] && refit[i]->numberOfValidHits())
00091       ? trackProbability(refit[i]) : 0.0; 
00092 
00093 //  std::cout << "Probabilities: " << prob[0] << " " << prob[1] << " " << prob[2] << " " << prob[3] << std::endl;
00094 
00095   if (prob[1] ) result = refit[1];
00096   if ((prob[1] == 0) && prob[3]) result = refit[3];
00097   
00098   if (prob[1] && prob[3] && ((prob[1] - prob[3]) > 0.05 ))  result = refit[3];
00099 
00100   if (prob[0] && prob[2] && fabs(prob[2] - prob[0]) > 30.) {
00101     result = refit[0];
00102     return result;
00103   }
00104 
00105   if ((prob[1] == 0) && (prob[3] == 0) && prob[2]) result = refit[2];
00106 
00107   reco::TrackRef tmin;
00108   double probmin = 0.0;
00109 
00110   if (prob[1] && prob[3]) {
00111     probmin = prob[3]; tmin = refit[3];
00112     if ( prob[1] < prob[3] ) { probmin = prob[1]; tmin = refit[1]; }
00113   } else if ((prob[3] == 0) && prob[1]) { 
00114     probmin = prob[1]; tmin = refit[1]; 
00115   } else if ((prob[1] == 0) && prob[3]) {
00116     probmin = prob[3]; tmin = refit[3]; 
00117   }
00118 
00119   if (probmin && prob[2] && ( (probmin - prob[2]) > 3.5 )) {
00120     result = refit[2];
00121   }
00122 
00123   return result;
00124 }
00125 
00126 //
00127 // calculate the tail probability (-ln(P)) of a fit
00128 //
00129 double muon::trackProbability(const reco::TrackRef track) {
00130 
00131   int nDOF = (int)track->ndof();
00132   if ( nDOF > 0 && track->chi2()> 0) { 
00133     return -log(TMath::Prob(track->chi2(), nDOF));
00134   } else { 
00135     return 0.0;
00136   }
00137 
00138 }
00139 
00140 //
00141 // Get the sigma-switch decision (tracker-only versus global).
00142 //
00143 reco::TrackRef muon::sigmaSwitch(const reco::TrackRef& combinedTrack,
00144                                  const reco::TrackRef& trackerTrack,
00145                                  const double nSigma,
00146                                  const double ptThreshold) {
00147   // If either the global or tracker-only fits have pT below threshold
00148   // (default 200 GeV), return the tracker-only fit.
00149   if (combinedTrack->pt() < ptThreshold || trackerTrack->pt() < ptThreshold)
00150     return trackerTrack;
00151   
00152   // If both are above the pT threshold, compare the difference in
00153   // q/p: if less than two sigma of the tracker-only track, switch to
00154   // global. Otherwise, use tracker-only.
00155   const double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
00156   const double threshold = nSigma * trackerTrack->qoverpError();
00157   return delta > threshold ? trackerTrack : combinedTrack;
00158 }
00159 
00160 //
00161 // Get the TMR decision (tracker-only versus TPFMS).
00162 //
00163 reco::TrackRef muon::TMR(const reco::TrackRef& trackerTrack,
00164                          const reco::TrackRef& fmsTrack,
00165                          const double tune) {
00166   double probTK  = 0;
00167   double probFMS = 0;
00168   
00169   if (trackerTrack.isNonnull() && trackerTrack->numberOfValidHits())
00170     probTK = muon::trackProbability(trackerTrack);
00171   if (fmsTrack.isNonnull() && fmsTrack->numberOfValidHits())
00172     probFMS = muon::trackProbability(fmsTrack);
00173   
00174   bool TKok  = probTK > 0;
00175   bool FMSok = probFMS > 0;
00176 
00177   if (TKok && FMSok) {
00178     if (probFMS - probTK > tune)
00179       return trackerTrack;
00180     else
00181       return fmsTrack;
00182   }
00183   else if (FMSok)
00184     return fmsTrack;
00185   else if (TKok)
00186     return trackerTrack;
00187   else
00188     return reco::TrackRef();
00189 }