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 
15 
16 using namespace std;
17 
19 
21  const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
22 
23  LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
24 
25  TrajectoryContainer::iterator iter, jter;
26  Trajectory::DataContainer::const_iterator m1, m2;
27 
28  if ( trajC.size() < 1 ) return;
29 
30  LogTrace(metname) << "Number of trajectories in the container: " <<trajC.size()<< endl;
31 
32  int i(0), j(0);
33  int match(0);
34 
35  // Map between chosen seed and ghost seeds (for trigger)
36  map<int, vector<int> > seedmap;
37 
38  // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
39  // This is fine as long as only operator [] is used as in this case.
40  // cf. par 16.3.11
41  vector<bool> mask(trajC.size(),true);
42 
44 
45  for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
46  if ( !mask[i] ) { i++; continue; }
47  if ( !(*iter)->isValid() || (*iter)->empty() ) {mask[i] = false; i++; continue; }
48  if(seedmap.count(i)==0) seedmap[i].push_back(i);
49  const Trajectory::DataContainer& meas1 = (*iter)->measurements();
50  j = i+1;
51  bool skipnext=false;
52  for ( jter = iter+1; jter != trajC.end(); jter++ ) {
53  if ( !mask[j] ) { j++; continue; }
54  if(seedmap.count(j)==0) seedmap[j].push_back(j);
55  const Trajectory::DataContainer& meas2 = (*jter)->measurements();
56  match = 0;
57  for( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
58  for( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
59  if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
60  } // end for( m2 ... )
61  } // end for( m1 ... )
62 
63 
64  int nTotHits_i = (*iter)->measurements().size();
65  int nTotHits_j = (*jter)->measurements().size();
66 
67  // FIXME Set Boff/on via cfg!
68  double chi2_dof_i = (*iter)->ndof() > 0 ? (*iter)->chiSquared()/(*iter)->ndof() : (*iter)->chiSquared()/1e-10;
69  double chi2_dof_j = (*jter)->ndof() > 0 ? (*jter)->chiSquared()/(*jter)->ndof() : (*jter)->chiSquared()/1e-10;
70 
71  LogTrace(metname) << " MuonTrajectoryCleaner:";
72  LogTrace(metname) << " * trajC " << i
73  << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
74  << " GeV) - chi2/nDOF = " << (*iter)->chiSquared() << "/" << (*iter)->ndof() << " = " << chi2_dof_i;
75  LogTrace(metname) << " - valid RH = " << (*iter)->foundHits() << " / total RH = " << nTotHits_i;
76  LogTrace(metname) << " * trajC " << j
77  << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
78  << " GeV) - chi2/nDOF = " << (*jter)->chiSquared() << "/" << (*jter)->ndof() << " = " << chi2_dof_j;
79  LogTrace(metname) << " - valid RH = " << (*jter)->foundHits() << " / total RH = " << nTotHits_j;
80  LogTrace(metname) << " *** Shared RecHits: " << match;
81 
82  int hit_diff = (*iter)->foundHits() - (*jter)->foundHits() ;
83  // If there are matches, reject the worst track
84  if ( match > 0 ) {
85  // If the difference in # of rechits is null then compare the chi2/ndf of the two trajectories
86  if ( abs(hit_diff) == 0 ) {
87 
88  double minPt = 3.5;
89  double dPt = 7.; // i.e. considering 10% (conservative!) resolution at minPt it is ~ 10 sigma away from the central value
90 
91  double maxFraction = 0.95;
92 
93  double fraction = (2.*match)/((*iter)->measurements().size()+(*jter)->measurements().size());
94  int belowLimit = 0;
95  int above = 0;
96 
97  if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
98  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() <= minPt) ++belowLimit;
99 
100  if((*jter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
101  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() >= dPt) ++above;
102 
103 
104  if(fraction >= maxFraction && belowLimit == 1 && above == 1){
105  if((*iter)->lastMeasurement().updatedState().globalMomentum().perp() < minPt){
106  mask[i] = false;
107  skipnext=true;
108  seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
109  seedmap.erase(i);
110  LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp()
111  << " GeV) rejected because it has too low pt";
112  }
113  else {
114  mask[j] = false;
115  seedmap[i].insert(seedmap[i].end(), seedmap[j].begin(), seedmap[j].end());
116  seedmap.erase(j);
117  LogTrace(metname) << "Trajectory # " << j << " (pT="<<(*jter)->lastMeasurement().updatedState().globalMomentum().perp()
118  << " GeV) rejected because it has too low pt";
119  }
120  }
121  else{
122  if (chi2_dof_i > chi2_dof_j) {
123  mask[i] = false;
124  skipnext=true;
125  seedmap[j].insert(seedmap[j].end(), seedmap[i].begin(), seedmap[i].end());
126  seedmap.erase(i);
127  LogTrace(metname) << "Trajectory # " << i << " (pT="<<(*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV) rejected";
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() << " GeV) rejected";
134  }
135  }
136  }
137  else { // different number of hits
138  if ( hit_diff < 0 ) {
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  if(skipnext) break;
154  j++;
155  }
156  i++;
157  if(skipnext) continue;
158  }
159 
160 
161  // Association map between the seed of the chosen trajectory and the seeds of the discarded trajectories
162  if(reportGhosts_) {
163  LogTrace(metname) << " Creating map between chosen seed and ghost seeds." << std::endl;
164 
165  auto_ptr<L2SeedAssoc> seedToSeedsMap(new L2SeedAssoc);
166  int seedcnt(0);
167 
168  for(map<int, vector<int> >::iterator itmap=seedmap.begin(); itmap!=seedmap.end(); ++itmap, ++seedcnt) {
169  edm::RefToBase<TrajectorySeed> tmpSeedRef1 = trajC[(*itmap).first]->seedRef();
171 
172  int tmpsize=(*itmap).second.size();
173  for(int cnt=0; cnt!=tmpsize; ++cnt) {
174  edm::RefToBase<TrajectorySeed> tmpSeedRef2 = trajC[(*itmap).second[cnt]]->seedRef();
176  seedToSeedsMap->insert(tmpL2SeedRef1, tmpL2SeedRef2);
177  }
178  }
179 
180  event.put(seedToSeedsMap, "");
181 
182  } // end if(reportGhosts_)
183 
184  i = 0;
185  for ( iter = trajC.begin(); iter != trajC.end(); iter++ ) {
186  if ( mask[i] ){
187  result.push_back(*iter);
188  LogTrace(metname) << "Keep trajectory with pT = " << (*iter)->lastMeasurement().updatedState().globalMomentum().perp() << " GeV";
189  }
190  else delete *iter;
191  i++;
192  }
193 
194  trajC.clear();
195  trajC = result;
196 }
197 
198 //
199 // clean CandidateContainer
200 //
202  const std::string metname = "Muon|RecoMuon|MuonTrajectoryCleaner";
203 
204  LogTrace(metname) << "Muon Trajectory Cleaner called" << endl;
205 
206  if ( candC.size() < 2 ) return;
207 
208  CandidateContainer::iterator iter, jter;
209  Trajectory::DataContainer::const_iterator m1, m2;
210 
211  const float deltaEta = 0.01;
212  const float deltaPhi = 0.01;
213  const float deltaPt = 1.0;
214 
215  LogTrace(metname) << "Number of muon candidates in the container: " <<candC.size()<< endl;
216 
217  int i(0), j(0);
218  int match(0);
219  //unused bool directionMatch = false;
220 
221  // CAVEAT: vector<bool> is not a vector, its elements are not addressable!
222  // This is fine as long as only operator [] is used as in this case.
223  // cf. par 16.3.11
224  vector<bool> mask(candC.size(),true);
225 
227 
228  for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
229  if ( !mask[i] ) { i++; continue; }
230  const Trajectory::DataContainer& meas1 = (*iter)->trajectory()->measurements();
231  j = i+1;
232  bool skipnext=false;
233 
234  TrajectoryStateOnSurface innerTSOS;
235 
236  if ((*iter)->trajectory()->direction() == alongMomentum) {
237  innerTSOS = (*iter)->trajectory()->firstMeasurement().updatedState();
238  }
239  else if ((*iter)->trajectory()->direction() == oppositeToMomentum) {
240  innerTSOS = (*iter)->trajectory()->lastMeasurement().updatedState();
241  }
242  if ( !(innerTSOS.isValid()) ) continue;
243  float pt1 = innerTSOS.globalMomentum().perp();
244  float eta1 = innerTSOS.globalMomentum().eta();
245  float phi1 = innerTSOS.globalMomentum().phi();
246 
247  for ( jter = iter+1; jter != candC.end(); jter++ ) {
248  if ( !mask[j] ) { j++; continue; }
249  //UNUSED: directionMatch = false;
250  const Trajectory::DataContainer& meas2 = (*jter)->trajectory()->measurements();
251  match = 0;
252  for ( m1 = meas1.begin(); m1 != meas1.end(); m1++ ) {
253  for ( m2 = meas2.begin(); m2 != meas2.end(); m2++ ) {
254  if ( (*m1).recHit()->isValid() && (*m2).recHit()->isValid() )
255  if ( ( (*m1).recHit()->globalPosition() - (*m2).recHit()->globalPosition()).mag()< 10e-5 ) match++;
256  }
257  }
258 
259  LogTrace(metname)
260  << " MuonTrajectoryCleaner: candC " << i << " chi2/nRH = "
261  << (*iter)->trajectory()->chiSquared() << "/" << (*iter)->trajectory()->foundHits() <<
262  " vs trajC " << j << " chi2/nRH = " << (*jter)->trajectory()->chiSquared() <<
263  "/" << (*jter)->trajectory()->foundHits() << " Shared RecHits: " << match;
264 
265  TrajectoryStateOnSurface innerTSOS2;
266  if ((*jter)->trajectory()->direction() == alongMomentum) {
267  innerTSOS2 = (*jter)->trajectory()->firstMeasurement().updatedState();
268  }
269  else if ((*jter)->trajectory()->direction() == oppositeToMomentum) {
270  innerTSOS2 = (*jter)->trajectory()->lastMeasurement().updatedState();
271  }
272  if ( !(innerTSOS2.isValid()) ) continue;
273 
274  float pt2 = innerTSOS2.globalMomentum().perp();
275  float eta2 = innerTSOS2.globalMomentum().eta();
276  float phi2 = innerTSOS2.globalMomentum().phi();
277 
278  float deta(fabs(eta1-eta2));
279  float dphi(fabs(Geom::Phi<float>(phi1)-Geom::Phi<float>(phi2)));
280  float dpt(fabs(pt1-pt2));
281  if ( dpt < deltaPt && deta < deltaEta && dphi < deltaPhi ) {
282  //UNUSED: directionMatch = true;
283  LogTrace(metname)
284  << " MuonTrajectoryCleaner: candC " << i<<" and "<<j<< " direction matched: "
285  <<innerTSOS.globalMomentum()<<" and " <<innerTSOS2.globalMomentum();
286  }
287 
288  // If there are matches, reject the worst track
289  bool hitsMatch = ((match > 0) && ((match/((*iter)->trajectory()->foundHits()) > 0.25) || (match/((*jter)->trajectory()->foundHits()) > 0.25))) ? true : false;
290  bool tracksMatch =
291  ( ( (*iter)->trackerTrack() == (*jter)->trackerTrack() ) &&
292  ( deltaR<double>((*iter)->muonTrack()->eta(),(*iter)->muonTrack()->phi(), (*jter)->muonTrack()->eta(),(*jter)->muonTrack()->phi()) < 0.2) );
293 
294  //if ( ( tracksMatch ) || (hitsMatch > 0) || directionMatch ) {
295  if ( ( tracksMatch ) || (hitsMatch > 0) ) {
296  if ( (*iter)->trajectory()->foundHits() == (*jter)->trajectory()->foundHits() ) {
297  if ( (*iter)->trajectory()->chiSquared() > (*jter)->trajectory()->chiSquared() ) {
298  mask[i] = false;
299  skipnext=true;
300  }
301  else mask[j] = false;
302  }
303  else { // different number of hits
304  if ( (*iter)->trajectory()->foundHits() < (*jter)->trajectory()->foundHits() ) {
305  mask[i] = false;
306  skipnext=true;
307  }
308  else mask[j] = false;
309  }
310  }
311  if(skipnext) break;
312  j++;
313  }
314  i++;
315  if(skipnext) continue;
316  }
317 
318  i = 0;
319  for ( iter = candC.begin(); iter != candC.end(); iter++ ) {
320  if ( mask[i] ) {
321  result.push_back(*iter);
322  } else {
323  delete (*iter)->trajectory();
324  delete (*iter)->trackerTrajectory();
325  delete *iter;
326  }
327  i++;
328  }
329 
330  candC.clear();
331  candC = result;
332 }
333 
int i
Definition: DBlmapReader.cc:9
T perp() const
Definition: PV3DBase.h:72
const std::string metname
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
edm::AssociationMap< edm::OneToMany< L2MuonTrajectorySeedCollection, L2MuonTrajectorySeedCollection > > L2SeedAssoc
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
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
#define end
Definition: vmac.h:37
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)
MuonCandidate::TrajectoryContainer TrajectoryContainer
REF castTo() const
cast to a concrete type
Definition: RefToBase.h:241
T eta() const
Definition: PV3DBase.h:76
#define begin
Definition: vmac.h:30
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:10