CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonTrajectoryCleaner.cc
Go to the documentation of this file.
1 
17 
18 using namespace std;
19 
21 
23  const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
24 
25  LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
26 
27  TrajectoryContainer::iterator iter, jter;
28  Trajectory::DataContainer::const_iterator m1, m2;
29 
30  if ( trajC.size() < 1 ) return;
31 
32  LogTrace(metname) << "Number of trajectories in the container: " <<trajC.size()<< endl;
33 
34  int i(0), j(0);
35  int match(0);
36  int nTot1DHits_i(0), nTot1DHits_j(0); // tot number of 1D/2D hits (including invalid)
37 
38  // Map between chosen seed and ghost seeds (for trigger)
39  map<int, vector<int> > seedmap;
40 
41  // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
42  // This is fine as long as only operator [] is used as in this case.
43  // cf. par 16.3.11
44  vector<bool> mask(trajC.size(),true);
45 
47 
48  for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
49  if ( !mask[i] ) { i++; continue; }
50  if ( !(*iter)->isValid() || (*iter)->empty() ) {mask[i] = false; i++; continue; }
51  if(seedmap.count(i)==0) seedmap[i].push_back(i);
52  const Trajectory::DataContainer& meas1 = (*iter)->measurements();
53  j = i+1;
54  bool skipnext=false;
55  for ( jter = iter+1; jter != trajC.end(); jter++ ) {
56  if ( !mask[j] ) { j++; continue; }
57  if(seedmap.count(j)==0) seedmap[j].push_back(j);
58  const Trajectory::DataContainer& meas2 = (*jter)->measurements();
59  match = 0;
60  nTot1DHits_i = 0;
61  for( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
63  if((*m1).recHit()->dimension()==4) trhC1 = MuonTransientTrackingRecHitBreaker::breakInSubRecHits((*m1).recHit(), 2);
64  else trhC1.push_back((*m1).recHit());
65  for( TransientTrackingRecHit::ConstRecHitContainer::const_iterator trh1=trhC1.begin(); trh1!=trhC1.end(); ++trh1, ++nTot1DHits_i) {
66  nTot1DHits_j = 0;
67  for( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
69  if((*m2).recHit()->dimension()==4) trhC2 = MuonTransientTrackingRecHitBreaker::breakInSubRecHits((*m2).recHit(), 2);
70  else trhC2.push_back((*m2).recHit());
71  for( TransientTrackingRecHit::ConstRecHitContainer::const_iterator trh2=trhC2.begin(); trh2!=trhC2.end(); ++trh2, ++nTot1DHits_j) {
72  if( ( (*trh1)->globalPosition() - (*trh2)->globalPosition()).mag() < 10e-5 ) match++;
73  // if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
74  } // end for( trh2 ... )
75  } // end for( m2 ... )
76  } // end for( trh1 ... )
77  } // end for( m1 ... )
78 
79 
80  int nTotHits_i = (*iter)->measurements().size();
81  int nTotHits_j = (*jter)->measurements().size();
82 
83  // FIXME Set Boff/on via cfg!
84  double chi2_dof_i = (*iter)->ndof() > 0 ? (*iter)->chiSquared()/(*iter)->ndof() : (*iter)->chiSquared()/1e-10;
85  double chi2_dof_j = (*jter)->ndof() > 0 ? (*jter)->chiSquared()/(*jter)->ndof() : (*jter)->chiSquared()/1e-10;
86 
87  LogTrace(metname) << " MuonTrajectoryCleaner:";
88  LogTrace(metname) << " * trajC " << i
89  << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
90  << " GeV) - chi2/nDOF = " << (*iter)->chiSquared() << "/" << (*iter)->ndof() << " = " << chi2_dof_i;
91  LogTrace(metname) << " - valid RH = " << (*iter)->foundHits() << " / total RH = " << nTotHits_i << " / total 1D RH = " << nTot1DHits_i;
92  LogTrace(metname) << " * trajC " << j
93  << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
94  << " GeV) - chi2/nDOF = " << (*jter)->chiSquared() << "/" << (*jter)->ndof() << " = " << chi2_dof_j;
95  LogTrace(metname) << " - valid RH = " << (*jter)->foundHits() << " / total RH = " << nTotHits_j << " / total 1D RH = " << nTot1DHits_j;
96  LogTrace(metname) << " *** Shared 1D RecHits: " << match;
97 
98  int hit_diff = (*iter)->foundHits() - (*jter)->foundHits() ;
99  // If there are matches, reject the worst track
100  if ( match > 0 ) {
101  // If the difference of # of rechits is less than 4, compare the chi2/ndf
102  if ( abs(hit_diff) <= 4 ) {
103 
104  double minPt = 3.5;
105  double dPt = 7.; // i.e. considering 10% (conservative!) resolution at minPt it is ~ 10 sigma away from the central value
106 
107  double maxFraction = 0.95;
108 
109  double fraction = (2.*match)/((*iter)->measurements().size()+(*jter)->measurements().size());
110  int belowLimit = 0;
111  int above = 0;
112 
113  if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
114  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
115 
116  if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
117  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
118 
119 
120  if(fraction >= maxFraction && belowLimit == 1 && above == 1){
121  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() < minPt){
122  mask[i] = false;
123  skipnext=true;
124  seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
125  seedmap.erase(i);
126  LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
127  << " GeV) rejected because it has too low pt";
128  }
129  else {
130  mask[j] = false;
131  seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
132  seedmap.erase(j);
133  LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
134  << " GeV) rejected because it has too low pt";
135  }
136  }
137  else{
138  if (chi2_dof_i > chi2_dof_j) {
139  mask[i] = false;
140  skipnext=true;
141  seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
142  seedmap.erase(i);
143  LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
144  }
145  else{
146  mask[j] = false;
147  seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
148  seedmap.erase(j);
149  LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
150  }
151  }
152  }
153  else { // different number of hits
154  if ( hit_diff < 0 ) {
155  mask[i] = false;
156  skipnext=true;
157  seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
158  seedmap.erase(i);
159  LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
160  }
161  else {
162  mask[j] = false;
163  seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
164  seedmap.erase(j);
165  LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
166  }
167  }
168  }
169  if(skipnext) break;
170  j++;
171  }
172  i++;
173  if(skipnext) continue;
174  }
175 
176 
177  // Association map between the seed of the chosen trajectory and the seeds of the discarded trajectories
178  if(reportGhosts_) {
179  LogTrace(metname) << " Creating map between chosen seed and ghost seeds." << std::endl;
180 
181  auto_ptr<L2SeedAssoc> seedToSeedsMap(new L2SeedAssoc);
182  int seedcnt(0);
183 
184  for(map<int, vector<int> >::iterator itmap=seedmap.begin(); itmap!=seedmap.end(); ++itmap, ++seedcnt) {
185  edm::RefToBase<TrajectorySeed> tmpSeedRef1 = trajC[(*itmap).first]->seedRef();
187 
188  int tmpsize=(*itmap).second.size();
189  for(int cnt=0; cnt!=tmpsize; ++cnt) {
190  edm::RefToBase<TrajectorySeed> tmpSeedRef2 = trajC[(*itmap).second[cnt]]->seedRef();
192  seedToSeedsMap->insert(tmpL2SeedRef1, tmpL2SeedRef2);
193  }
194  }
195 
196  event.put(seedToSeedsMap, "");
197 
198  } // end if(reportGhosts_)
199 
200  i = 0;
201  for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
202  if ( mask[i] ){
203  result.push_back(*iter);
204  LogTrace(metname) << "Keep trajectory with pT = " << (*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV";
205  }
206  else delete *iter;
207  i++;
208  }
209 
210  trajC.clear();
211  trajC = result;
212 }
213 
214 //
215 // clean CandidateContainer
216 //
218  const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
219 
220  LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
221 
222  if ( candC.size() < 2 ) return;
223 
224  CandidateContainer::iterator iter, jter;
225  Trajectory::DataContainer::const_iterator m1, m2;
226 
227  const float deltaEta = 0.01;
228  const float deltaPhi = 0.01;
229  const float deltaPt = 1.0;
230 
231  LogTrace(metname) << "Number of muon candidates in the container: " <<candC.size()<< endl;
232 
233  int i(0), j(0);
234  int match(0);
235  bool directionMatch = false;
236 
237  // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
238  // This is fine as long as only operator [] is used as in this case.
239  // cf. par 16.3.11
240  vector<bool> mask(candC.size(),true);
241 
243 
244  for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
245  if ( !mask[i] ) { i++; continue; }
246  const Trajectory::DataContainer& meas1 = (*iter)->trajectory()->measurements();
247  j = i+1;
248  bool skipnext=false;
249 
250  TrajectoryStateOnSurface innerTSOS;
251 
252  if ((*iter)->trajectory()->direction() == alongMomentum) {
253  innerTSOS = (*iter)->trajectory()->firstMeasurement().updatedState();
254  }
255  else if ((*iter)->trajectory()->direction() == oppositeToMomentum) {
256  innerTSOS = (*iter)->trajectory()->lastMeasurement().updatedState();
257  }
258  if ( !(innerTSOS.isValid()) ) continue;
259  float pt1 = innerTSOS.globalMomentum().perp();
260  float eta1 = innerTSOS.globalMomentum().eta();
261  float phi1 = innerTSOS.globalMomentum().phi();
262 
263  for ( jter = iter+1; jter != candC.end(); jter++ ) {
264  if ( !mask[j] ) { j++; continue; }
265  directionMatch = false;
266  const Trajectory::DataContainer& meas2 = (*jter)->trajectory()->measurements();
267  match = 0;
268  for ( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
269  for ( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
270  if ( (*m1).recHit()->isValid() && (*m2).recHit()->isValid() )
271  if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
272  }
273  }
274 
275  LogTrace(metname)
276  << " MuonTrajectoryCleaner: candC " << i << " chi2/nRH = "
277  << (*iter)->trajectory()->chiSquared() << "/" << (*iter)->trajectory()->foundHits() <<
278  " vs trajC " << j << " chi2/nRH = " << (*jter)->trajectory()->chiSquared() <<
279  "/" << (*jter)->trajectory()->foundHits() << " Shared RecHits: " << match;
280 
281  TrajectoryStateOnSurface innerTSOS2;
282  if ((*jter)->trajectory()->direction() == alongMomentum) {
283  innerTSOS2 = (*jter)->trajectory()->firstMeasurement().updatedState();
284  }
285  else if ((*jter)->trajectory()->direction() == oppositeToMomentum) {
286  innerTSOS2 = (*jter)->trajectory()->lastMeasurement().updatedState();
287  }
288  if ( !(innerTSOS2.isValid()) ) continue;
289 
290  float pt2 = innerTSOS2.globalMomentum().perp();
291  float eta2 = innerTSOS2.globalMomentum().eta();
292  float phi2 = innerTSOS2.globalMomentum().phi();
293 
294  float deta(fabs(eta1-eta2));
295  float dphi(fabs(Geom::Phi<float>(phi1)-Geom::Phi<float>(phi2)));
296  float dpt(fabs(pt1-pt2));
297  if ( dpt < deltaPt && deta < deltaEta && dphi < deltaPhi ) {
298  directionMatch = true;
299  LogTrace(metname)
300  << " MuonTrajectoryCleaner: candC " << i<<" and "<<j<< " direction matched: "
301  <<innerTSOS.globalMomentum()<<" and " <<innerTSOS2.globalMomentum();
302  }
303 
304  // If there are matches, reject the worst track
305  bool hitsMatch = ((match > 0) && ((match/((*iter)->trajectory()->foundHits()) > 0.25) || (match/((*jter)->trajectory()->foundHits()) > 0.25))) ? true : false;
306  bool tracksMatch =
307  ( ( (*iter)->trackerTrack() == (*jter)->trackerTrack() ) &&
308  ( deltaR<double>((*iter)->muonTrack()->eta(),(*iter)->muonTrack()->phi(), (*jter)->muonTrack()->eta(),(*jter)->muonTrack()->phi()) < 0.2) );
309 
310  //if ( ( tracksMatch ) || (hitsMatch > 0) || directionMatch ) {
311  if ( ( tracksMatch ) || (hitsMatch > 0) ) {
312  if ( (*iter)->trajectory()->foundHits() == (*jter)->trajectory()->foundHits() ) {
313  if ( (*iter)->trajectory()->chiSquared() > (*jter)->trajectory()->chiSquared() ) {
314  mask[i] = false;
315  skipnext=true;
316  }
317  else mask[j] = false;
318  }
319  else { // different number of hits
320  if ( (*iter)->trajectory()->foundHits() < (*jter)->trajectory()->foundHits() ) {
321  mask[i] = false;
322  skipnext=true;
323  }
324  else mask[j] = false;
325  }
326  }
327  if(skipnext) break;
328  j++;
329  }
330  i++;
331  if(skipnext) continue;
332  }
333 
334  i = 0;
335  for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
336  if ( mask[i] ) {
337  result.push_back(*iter);
338  } else {
339  delete (*iter)->trajectory();
340  delete (*iter)->trackerTrajectory();
341  delete *iter;
342  }
343  i++;
344  }
345 
346  candC.clear();
347  candC = result;
348 }
349 
int i
Definition: DBlmapReader.cc:9
T perp() const
Definition: PV3DBase.h:66
const std::string metname
double deltaPhi(float phi1, float phi2)
Definition: VectorUtil.h:30
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Geom::Phi< T > phi() const
Definition: PV3DBase.h:63
#define abs(x)
Definition: mlp_lapack.h:159
edm::AssociationMap< edm::OneToMany< L2MuonTrajectorySeedCollection, L2MuonTrajectorySeedCollection > > L2SeedAssoc
static TransientTrackingRecHit::ConstRecHitContainer breakInSubRecHits(TransientTrackingRecHit::ConstRecHitPointer, int granularity)
takes a muon rechit and returns its sub-rechits given a certain granularity
void clean(TrajectoryContainer &muonTrajectories, edm::Event &evt)
Clean the trajectories container, erasing the (worst) clone trajectory.
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
MuonCandidate::CandidateContainer CandidateContainer
tuple result
Definition: query.py:137
int j
Definition: DBlmapReader.cc:9
#define end
Definition: vmac.h:38
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
#define LogTrace(id)
std::vector< ConstRecHitPointer > ConstRecHitContainer
MuonCandidate::TrajectoryContainer TrajectoryContainer
REF castTo() const
cast to a concrete type
Definition: RefToBase.h:241
T eta() const
Definition: PV3DBase.h:70
#define begin
Definition: vmac.h:31
GlobalVector globalMomentum() const
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6