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
00030
00031
00032 vector<bool> mask(trajC.size(),true);
00033
00034 TrajectoryContainer result;
00035
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
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
00070 if ( match > 0 ) {
00071
00072 if ( abs(hit_diff) <= 4 ) {
00073
00074 double minPt = 3.5;
00075 double dPt = 7.;
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 {
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
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
00172
00173
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
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 {
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