Go to the documentation of this file.00001
00008 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryCleaner.h"
00009 #include "DataFormats/TrackReco/interface/Track.h"
00010 #include "DataFormats/Math/interface/deltaR.h"
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "DataFormats/Common/interface/RefToBase.h"
00013 #include "DataFormats/Common/interface/AssociationMap.h"
00014 #include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h"
00015 #include "DataFormats/TrackingRecHit/interface/RecSegment.h"
00016 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBreaker.h"
00017
00018 using namespace std;
00019
00020 typedef edm::AssociationMap<edm::OneToMany<L2MuonTrajectorySeedCollection, L2MuonTrajectorySeedCollection> > L2SeedAssoc;
00021
00022 void MuonTrajectoryCleaner::clean(TrajectoryContainer& trajC, edm::Event& event) {
00023 const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
00024
00025 LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
00026
00027 TrajectoryContainer::iterator iter, jter;
00028 Trajectory::DataContainer::const_iterator m1, m2;
00029
00030 if ( trajC.size() < 1 ) return;
00031
00032 LogTrace(metname) << "Number of trajectories in the container: " <<trajC.size()<< endl;
00033
00034 int i(0), j(0);
00035 int match(0);
00036 int nTot1DHits_i(0), nTot1DHits_j(0);
00037
00038
00039 map<int, vector<int> > seedmap;
00040
00041
00042
00043
00044 vector<bool> mask(trajC.size(),true);
00045
00046 TrajectoryContainer result;
00047
00048 for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
00049 if ( !mask[i] ) { i++; continue; }
00050 if ( !(*iter)->isValid() || (*iter)->empty() ) {mask[i] = false; i++; continue; }
00051 if(seedmap.count(i)==0) seedmap[i].push_back(i);
00052 const Trajectory::DataContainer& meas1 = (*iter)->measurements();
00053 j = i+1;
00054 bool skipnext=false;
00055 for ( jter = iter+1; jter != trajC.end(); jter++ ) {
00056 if ( !mask[j] ) { j++; continue; }
00057 if(seedmap.count(j)==0) seedmap[j].push_back(j);
00058 const Trajectory::DataContainer& meas2 = (*jter)->measurements();
00059 match = 0;
00060 nTot1DHits_i = 0;
00061 for( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
00062 TransientTrackingRecHit::ConstRecHitContainer trhC1;
00063 if((*m1).recHit()->dimension()==4) trhC1 = MuonTransientTrackingRecHitBreaker::breakInSubRecHits((*m1).recHit(), 2);
00064 else trhC1.push_back((*m1).recHit());
00065 for( TransientTrackingRecHit::ConstRecHitContainer::const_iterator trh1=trhC1.begin(); trh1!=trhC1.end(); ++trh1, ++nTot1DHits_i) {
00066 nTot1DHits_j = 0;
00067 for( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
00068 TransientTrackingRecHit::ConstRecHitContainer trhC2;
00069 if((*m2).recHit()->dimension()==4) trhC2 = MuonTransientTrackingRecHitBreaker::breakInSubRecHits((*m2).recHit(), 2);
00070 else trhC2.push_back((*m2).recHit());
00071 for( TransientTrackingRecHit::ConstRecHitContainer::const_iterator trh2=trhC2.begin(); trh2!=trhC2.end(); ++trh2, ++nTot1DHits_j) {
00072 if( ( (*trh1)->globalPosition() - (*trh2)->globalPosition()).mag() < 10e-5 ) match++;
00073
00074 }
00075 }
00076 }
00077 }
00078
00079
00080 int nTotHits_i = (*iter)->measurements().size();
00081 int nTotHits_j = (*jter)->measurements().size();
00082
00083
00084 double chi2_dof_i = (*iter)->ndof() > 0 ? (*iter)->chiSquared()/(*iter)->ndof() : (*iter)->chiSquared()/1e-10;
00085 double chi2_dof_j = (*jter)->ndof() > 0 ? (*jter)->chiSquared()/(*jter)->ndof() : (*jter)->chiSquared()/1e-10;
00086
00087 LogTrace(metname) << " MuonTrajectoryCleaner:";
00088 LogTrace(metname) << " * trajC " << i
00089 << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
00090 << " GeV) - chi2/nDOF = " << (*iter)->chiSquared() << "/" << (*iter)->ndof() << " = " << chi2_dof_i;
00091 LogTrace(metname) << " - valid RH = " << (*iter)->foundHits() << " / total RH = " << nTotHits_i << " / total 1D RH = " << nTot1DHits_i;
00092 LogTrace(metname) << " * trajC " << j
00093 << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
00094 << " GeV) - chi2/nDOF = " << (*jter)->chiSquared() << "/" << (*jter)->ndof() << " = " << chi2_dof_j;
00095 LogTrace(metname) << " - valid RH = " << (*jter)->foundHits() << " / total RH = " << nTotHits_j << " / total 1D RH = " << nTot1DHits_j;
00096 LogTrace(metname) << " *** Shared 1D RecHits: " << match;
00097
00098 int hit_diff = (*iter)->foundHits() - (*jter)->foundHits() ;
00099
00100 if ( match > 0 ) {
00101
00102 if ( abs(hit_diff) <= 4 ) {
00103
00104 double minPt = 3.5;
00105 double dPt = 7.;
00106
00107 double maxFraction = 0.95;
00108
00109 double fraction = (2.*match)/((*iter)->measurements().size()+(*jter)->measurements().size());
00110 int belowLimit = 0;
00111 int above = 0;
00112
00113 if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
00114 if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
00115
00116 if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
00117 if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
00118
00119
00120 if(fraction >= maxFraction && belowLimit == 1 && above == 1){
00121 if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() < minPt){
00122 mask[i] = false;
00123 skipnext=true;
00124 seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
00125 seedmap.erase(i);
00126 LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
00127 << " GeV) rejected because it has too low pt";
00128 }
00129 else {
00130 mask[j] = false;
00131 seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
00132 seedmap.erase(j);
00133 LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
00134 << " GeV) rejected because it has too low pt";
00135 }
00136 }
00137 else{
00138 if (chi2_dof_i > chi2_dof_j) {
00139 mask[i] = false;
00140 skipnext=true;
00141 seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
00142 seedmap.erase(i);
00143 LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00144 }
00145 else{
00146 mask[j] = false;
00147 seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
00148 seedmap.erase(j);
00149 LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00150 }
00151 }
00152 }
00153 else {
00154 if ( hit_diff < 0 ) {
00155 mask[i] = false;
00156 skipnext=true;
00157 seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
00158 seedmap.erase(i);
00159 LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00160 }
00161 else {
00162 mask[j] = false;
00163 seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
00164 seedmap.erase(j);
00165 LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
00166 }
00167 }
00168 }
00169 if(skipnext) break;
00170 j++;
00171 }
00172 i++;
00173 if(skipnext) continue;
00174 }
00175
00176
00177
00178 if(reportGhosts_) {
00179 LogTrace(metname) << " Creating map between chosen seed and ghost seeds." << std::endl;
00180
00181 auto_ptr<L2SeedAssoc> seedToSeedsMap(new L2SeedAssoc);
00182 int seedcnt(0);
00183
00184 for(map<int, vector<int> >::iterator itmap=seedmap.begin(); itmap!=seedmap.end(); ++itmap, ++seedcnt) {
00185 edm::RefToBase<TrajectorySeed> tmpSeedRef1 = trajC[(*itmap).first]->seedRef();
00186 edm::Ref<L2MuonTrajectorySeedCollection> tmpL2SeedRef1 = tmpSeedRef1.castTo<edm::Ref<L2MuonTrajectorySeedCollection> >();
00187
00188 int tmpsize=(*itmap).second.size();
00189 for(int cnt=0; cnt!=tmpsize; ++cnt) {
00190 edm::RefToBase<TrajectorySeed> tmpSeedRef2 = trajC[(*itmap).second[cnt]]->seedRef();
00191 edm::Ref<L2MuonTrajectorySeedCollection> tmpL2SeedRef2 = tmpSeedRef2.castTo<edm::Ref<L2MuonTrajectorySeedCollection> >();
00192 seedToSeedsMap->insert(tmpL2SeedRef1, tmpL2SeedRef2);
00193 }
00194 }
00195
00196 event.put(seedToSeedsMap, "");
00197
00198 }
00199
00200 i = 0;
00201 for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
00202 if ( mask[i] ){
00203 result.push_back(*iter);
00204 LogTrace(metname) << "Keep trajectory with pT = " << (*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV";
00205 }
00206 else delete *iter;
00207 i++;
00208 }
00209
00210 trajC.clear();
00211 trajC = result;
00212 }
00213
00214
00215
00216
00217 void MuonTrajectoryCleaner::clean(CandidateContainer& candC){
00218 const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
00219
00220 LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
00221
00222 if ( candC.size() < 2 ) return;
00223
00224 CandidateContainer::iterator iter, jter;
00225 Trajectory::DataContainer::const_iterator m1, m2;
00226
00227 const float deltaEta = 0.01;
00228 const float deltaPhi = 0.01;
00229 const float deltaPt = 1.0;
00230
00231 LogTrace(metname) << "Number of muon candidates in the container: " <<candC.size()<< endl;
00232
00233 int i(0), j(0);
00234 int match(0);
00235 bool directionMatch = false;
00236
00237
00238
00239
00240 vector<bool> mask(candC.size(),true);
00241
00242 CandidateContainer result;
00243
00244 for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
00245 if ( !mask[i] ) { i++; continue; }
00246 const Trajectory::DataContainer& meas1 = (*iter)->trajectory()->measurements();
00247 j = i+1;
00248 bool skipnext=false;
00249
00250 TrajectoryStateOnSurface innerTSOS;
00251
00252 if ((*iter)->trajectory()->direction() == alongMomentum) {
00253 innerTSOS = (*iter)->trajectory()->firstMeasurement().updatedState();
00254 }
00255 else if ((*iter)->trajectory()->direction() == oppositeToMomentum) {
00256 innerTSOS = (*iter)->trajectory()->lastMeasurement().updatedState();
00257 }
00258 if ( !(innerTSOS.isValid()) ) continue;
00259 float pt1 = innerTSOS.globalMomentum().perp();
00260 float eta1 = innerTSOS.globalMomentum().eta();
00261 float phi1 = innerTSOS.globalMomentum().phi();
00262
00263 for ( jter = iter+1; jter != candC.end(); jter++ ) {
00264 if ( !mask[j] ) { j++; continue; }
00265 directionMatch = false;
00266 const Trajectory::DataContainer& meas2 = (*jter)->trajectory()->measurements();
00267 match = 0;
00268 for ( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
00269 for ( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
00270 if ( (*m1).recHit()->isValid() && (*m2).recHit()->isValid() )
00271 if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
00272 }
00273 }
00274
00275 LogTrace(metname)
00276 << " MuonTrajectoryCleaner: candC " << i << " chi2/nRH = "
00277 << (*iter)->trajectory()->chiSquared() << "/" << (*iter)->trajectory()->foundHits() <<
00278 " vs trajC " << j << " chi2/nRH = " << (*jter)->trajectory()->chiSquared() <<
00279 "/" << (*jter)->trajectory()->foundHits() << " Shared RecHits: " << match;
00280
00281 TrajectoryStateOnSurface innerTSOS2;
00282 if ((*jter)->trajectory()->direction() == alongMomentum) {
00283 innerTSOS2 = (*jter)->trajectory()->firstMeasurement().updatedState();
00284 }
00285 else if ((*jter)->trajectory()->direction() == oppositeToMomentum) {
00286 innerTSOS2 = (*jter)->trajectory()->lastMeasurement().updatedState();
00287 }
00288 if ( !(innerTSOS2.isValid()) ) continue;
00289
00290 float pt2 = innerTSOS2.globalMomentum().perp();
00291 float eta2 = innerTSOS2.globalMomentum().eta();
00292 float phi2 = innerTSOS2.globalMomentum().phi();
00293
00294 float deta(fabs(eta1-eta2));
00295 float dphi(fabs(Geom::Phi<float>(phi1)-Geom::Phi<float>(phi2)));
00296 float dpt(fabs(pt1-pt2));
00297 if ( dpt < deltaPt && deta < deltaEta && dphi < deltaPhi ) {
00298 directionMatch = true;
00299 LogTrace(metname)
00300 << " MuonTrajectoryCleaner: candC " << i<<" and "<<j<< " direction matched: "
00301 <<innerTSOS.globalMomentum()<<" and " <<innerTSOS2.globalMomentum();
00302 }
00303
00304
00305 bool hitsMatch = ((match > 0) && ((match/((*iter)->trajectory()->foundHits()) > 0.25) || (match/((*jter)->trajectory()->foundHits()) > 0.25))) ? true : false;
00306 bool tracksMatch =
00307 ( ( (*iter)->trackerTrack() == (*jter)->trackerTrack() ) &&
00308 ( deltaR<double>((*iter)->muonTrack()->eta(),(*iter)->muonTrack()->phi(), (*jter)->muonTrack()->eta(),(*jter)->muonTrack()->phi()) < 0.2) );
00309
00310
00311 if ( ( tracksMatch ) || (hitsMatch > 0) ) {
00312 if ( (*iter)->trajectory()->foundHits() == (*jter)->trajectory()->foundHits() ) {
00313 if ( (*iter)->trajectory()->chiSquared() > (*jter)->trajectory()->chiSquared() ) {
00314 mask[i] = false;
00315 skipnext=true;
00316 }
00317 else mask[j] = false;
00318 }
00319 else {
00320 if ( (*iter)->trajectory()->foundHits() < (*jter)->trajectory()->foundHits() ) {
00321 mask[i] = false;
00322 skipnext=true;
00323 }
00324 else mask[j] = false;
00325 }
00326 }
00327 if(skipnext) break;
00328 j++;
00329 }
00330 i++;
00331 if(skipnext) continue;
00332 }
00333
00334 i = 0;
00335 for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
00336 if ( mask[i] ) {
00337 result.push_back(*iter);
00338 } else {
00339 delete (*iter)->trajectory();
00340 delete (*iter)->trackerTrajectory();
00341 delete *iter;
00342 }
00343 i++;
00344 }
00345
00346 candC.clear();
00347 candC = result;
00348 }
00349