CMS 3D CMS Logo

MuonTrajectoryCleaner.cc

Go to the documentation of this file.
00001 
00008 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryCleaner.h"
00009 
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 
00012 using namespace std; 
00013 
00014 void MuonTrajectoryCleaner::clean(TrajectoryContainer& trajC){ 
00015   const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
00016 
00017   LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
00018 
00019   TrajectoryContainer::iterator iter, jter;
00020   Trajectory::DataContainer::const_iterator m1, m2;
00021 
00022   if ( trajC.size() < 2 ) return;
00023   
00024   LogTrace(metname) << "Number of trajectories in the container: " <<trajC.size()<< endl;
00025 
00026   int i(0), j(0);
00027   int match(0);
00028 
00029   // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
00030   // This is fine as long as only operator [] is used as in this case.
00031   // cf. par 16.3.11
00032   vector<bool> mask(trajC.size(),true);
00033   
00034   TrajectoryContainer result;
00035   //  result.reserve(trajC.size());
00036   
00037   for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
00038     if ( !mask[i] ) { i++; continue; }
00039     const Trajectory::DataContainer& meas1 = (*iter)->measurements();
00040     j = i+1;
00041     bool skipnext=false;
00042     for ( jter = iter+1; jter != trajC.end(); jter++ ) {
00043       if ( !mask[j] ) { j++; continue; }
00044       const Trajectory::DataContainer& meas2 = (*jter)->measurements();
00045       match = 0;
00046       for ( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
00047         for ( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
00048           if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
00049         }
00050       }
00051       
00052 
00053       // FIXME Set Boff/on via cfg!
00054       double chi2_dof_i = (*iter)->chiSquared()/(*iter)->ndof();
00055       double chi2_dof_j = (*jter)->chiSquared()/(*jter)->ndof();
00056 
00057       LogTrace(metname) 
00058         << " MuonTrajSelector: trajC " 
00059         << i << "(pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV)"
00060         << " chi2/nDOF = " << (*iter)->chiSquared() << "/" << (*iter)->ndof() 
00061         << " (RH=" << (*iter)->foundHits() << ") = " << chi2_dof_i
00062         << " vs trajC " 
00063         << j << "(pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV)"
00064         << " chi2/nRH = " << (*jter)->chiSquared() << "/" <<  (*jter)->ndof() 
00065         << " (RH=" << (*jter)->foundHits() << ") = " << chi2_dof_j
00066         << " Shared RecHits: " << match; 
00067 
00068       int hit_diff =  (*iter)->foundHits() - (*jter)->foundHits() ;       
00069       // If there are matches, reject the worst track
00070       if ( match > 0 ) {
00071         // If the difference of # of rechits is less than 4, compare the chi2/ndf
00072         if ( abs(hit_diff) <= 4  ) {
00073 
00074           double minPt = 3.5;
00075           double dPt = 7.;  // i.e. considering 10% (conservative!) resolution at minPt it is ~ 10 sigma away from the central value
00076 
00077           double maxFraction = 0.95;
00078 
00079           double fraction = (2.*match)/((*iter)->foundHits()+(*jter)->foundHits());
00080           int belowLimit = 0;
00081           int above = 0;
00082 
00083           if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit; 
00084           if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit; 
00085          
00086           if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above; 
00087           if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above; 
00088           
00089 
00090           if(fraction >= maxFraction && belowLimit == 1 && above == 1){
00091             if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() < minPt){
00092               mask[i] = false;
00093               skipnext=true;
00094               LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() 
00095                                 << " GeV) rejected because it has too low pt";
00096             } 
00097             else {
00098               mask[j] = false;
00099               LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() 
00100                                 << " GeV) rejected because it has too low pt";
00101             }
00102           }
00103           else{   
00104             if (chi2_dof_i  > chi2_dof_j) {
00105               mask[i] = false;
00106               skipnext=true;
00107               LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00108             }
00109             else{
00110               mask[j] = false;
00111               LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00112             }
00113           }
00114         }
00115         else { // different number of hits
00116           if ( hit_diff < 0 ) {
00117             mask[i] = false;
00118             skipnext=true;
00119             LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00120           }
00121           else { 
00122             mask[j] = false;
00123             LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00124           }
00125         } 
00126       }
00127       if(skipnext) break;
00128       j++;
00129     }
00130     i++;
00131     if(skipnext) continue;
00132   }
00133   
00134   i = 0;
00135   for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
00136     if ( mask[i] ){
00137       result.push_back(*iter);
00138       LogTrace(metname) << "Keep trajectory with pT = " << (*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV";
00139     }
00140     else delete *iter;
00141     i++;
00142   }
00143   
00144   trajC.clear();
00145   trajC = result;
00146 }
00147 
00148 //
00149 // clean CandidateContainer
00150 //
00151 void MuonTrajectoryCleaner::clean(CandidateContainer& candC){ 
00152   const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
00153 
00154   LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
00155 
00156   if ( candC.size() < 2 ) return;
00157 
00158   CandidateContainer::iterator iter, jter;
00159   Trajectory::DataContainer::const_iterator m1, m2;
00160 
00161   const float deltaEta = 0.01;
00162   const float deltaPhi = 0.01;
00163   const float deltaPt  = 1.0;
00164   
00165   LogTrace(metname) << "Number of muon candidates in the container: " <<candC.size()<< endl;
00166 
00167   int i(0), j(0);
00168   int match(0);
00169   bool directionMatch = false;
00170 
00171   // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
00172   // This is fine as long as only operator [] is used as in this case.
00173   // cf. par 16.3.11
00174   vector<bool> mask(candC.size(),true);
00175   
00176   CandidateContainer result;
00177   
00178   for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
00179     if ( !mask[i] ) { i++; continue; }
00180     const Trajectory::DataContainer& meas1 = (*iter)->trajectory()->measurements();
00181     j = i+1;
00182     bool skipnext=false;
00183 
00184     TrajectoryStateOnSurface innerTSOS;
00185 
00186     if ((*iter)->trajectory()->direction() == alongMomentum) {
00187       innerTSOS = (*iter)->trajectory()->firstMeasurement().updatedState();
00188     } 
00189     else if ((*iter)->trajectory()->direction() == oppositeToMomentum) { 
00190       innerTSOS = (*iter)->trajectory()->lastMeasurement().updatedState();
00191     }
00192     if ( !(innerTSOS.isValid()) ) continue;
00193 
00194     float pt1 = innerTSOS.globalMomentum().perp();
00195     float eta1 = innerTSOS.globalMomentum().eta();
00196     float phi1 = innerTSOS.globalMomentum().phi();
00197 
00198     for ( jter = iter+1; jter != candC.end(); jter++ ) {
00199       if ( !mask[j] ) { j++; continue; }
00200       directionMatch = false;
00201       const Trajectory::DataContainer& meas2 = (*jter)->trajectory()->measurements();
00202       match = 0;
00203       for ( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
00204         for ( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
00205           if ( (*m1).recHit()->isValid() && (*m2).recHit()->isValid() ) 
00206             if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
00207         }
00208       }
00209       
00210       LogTrace(metname) 
00211         << " MuonTrajSelector: candC " << i << " chi2/nRH = " 
00212         << (*iter)->trajectory()->chiSquared() << "/" << (*iter)->trajectory()->foundHits() <<
00213         " vs trajC " << j << " chi2/nRH = " << (*jter)->trajectory()->chiSquared() <<
00214         "/" << (*jter)->trajectory()->foundHits() << " Shared RecHits: " << match;
00215 
00216       TrajectoryStateOnSurface innerTSOS2;       
00217       if ((*jter)->trajectory()->direction() == alongMomentum) {
00218         innerTSOS2 = (*jter)->trajectory()->firstMeasurement().updatedState();
00219       }
00220       else if ((*jter)->trajectory()->direction() == oppositeToMomentum) {
00221         innerTSOS2 = (*jter)->trajectory()->lastMeasurement().updatedState();
00222       }
00223       if ( !(innerTSOS2.isValid()) ) continue;
00224 
00225       float pt2 = innerTSOS2.globalMomentum().perp();
00226       float eta2 = innerTSOS2.globalMomentum().eta();
00227       float phi2 = innerTSOS2.globalMomentum().phi();
00228 
00229       float deta(fabs(eta1-eta2));
00230       float dphi(fabs(Geom::Phi<float>(phi1)-Geom::Phi<float>(phi2)));
00231       float dpt(abs(pt1-pt2));
00232       if ( dpt < deltaPt && deta < deltaEta && dphi < deltaPhi ) {
00233         directionMatch = true;
00234         LogTrace(metname)
00235         << " MuonTrajSelector: candC " << i<<" and "<<j<< " direction matched: "
00236         <<innerTSOS.globalMomentum()<<" and " <<innerTSOS2.globalMomentum();
00237 
00238       }
00239       
00240       // If there are matches, reject the worst track
00241       bool hitsMatch = ((match > 0) && (match/((*iter)->trajectory()->foundHits()) > 0.25) || (match/((*jter)->trajectory()->foundHits()) > 0.25)) ? true : false;
00242       
00243       if ( (hitsMatch > 0) || directionMatch ) {
00244         if (  (*iter)->trajectory()->foundHits() == (*jter)->trajectory()->foundHits() ) {
00245           if ( (*iter)->trajectory()->chiSquared() > (*jter)->trajectory()->chiSquared() ) {
00246             mask[i] = false;
00247             skipnext=true;
00248           }
00249           else mask[j] = false;
00250         }
00251         else { // different number of hits
00252           if ( (*iter)->trajectory()->foundHits() < (*jter)->trajectory()->foundHits() ) {
00253             mask[i] = false;
00254             skipnext=true;
00255           }
00256           else mask[j] = false;
00257         }
00258       }
00259       if(skipnext) break;
00260       j++;
00261     }
00262     i++;
00263     if(skipnext) continue;
00264   }
00265   
00266   i = 0;
00267   for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
00268     if ( mask[i] ) {
00269        result.push_back(*iter);
00270     } else {
00271        delete (*iter)->trajectory();
00272        delete (*iter)->trackerTrajectory();
00273        delete *iter;
00274     } 
00275     i++;
00276   }
00277   
00278   candC.clear();
00279   candC = result;
00280 }
00281 

Generated on Tue Jun 9 17:44:36 2009 for CMSSW by  doxygen 1.5.4