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