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