CMS 3D CMS Logo

GlobalMuonTrackMatcher.cc
Go to the documentation of this file.
1 
14 
15 //---------------
16 // C++ Headers --
17 //---------------
18 
19 
20 //-------------------------------
21 // Collaborating Class Headers --
22 //-------------------------------
23 
27 
33 
35 
38 
41 
43 
44 using namespace std;
45 using namespace reco;
46 
47 //
48 // constructor
49 //
51  const MuonServiceProxy* service) :
52  theService(service) {
53  theMinP = par.getParameter<double>("MinP");
54  theMinPt = par.getParameter<double>("MinPt");
55  thePt_threshold1 = par.getParameter<double>("Pt_threshold1");
56  thePt_threshold2 = par.getParameter<double>("Pt_threshold2");
57  theEta_threshold= par.getParameter<double>("Eta_threshold");
58  theChi2_1= par.getParameter<double>("Chi2Cut_1");
59  theChi2_2= par.getParameter<double>("Chi2Cut_2");
60  theChi2_3= par.getParameter<double>("Chi2Cut_3");
61  theLocChi2= par.getParameter<double>("LocChi2Cut");
62  theDeltaD_1= par.getParameter<double>("DeltaDCut_1");
63  theDeltaD_2= par.getParameter<double>("DeltaDCut_2");
64  theDeltaD_3= par.getParameter<double>("DeltaDCut_3");
65  theDeltaR_1= par.getParameter<double>("DeltaRCut_1");
66  theDeltaR_2= par.getParameter<double>("DeltaRCut_2");
67  theDeltaR_3= par.getParameter<double>("DeltaRCut_3");
68  theQual_1= par.getParameter<double>("Quality_1");
69  theQual_2= par.getParameter<double>("Quality_2");
70  theQual_3= par.getParameter<double>("Quality_3");
71  theOutPropagatorName = par.getParameter<string>("Propagator");
72 
73 }
74 
75 
76 //
77 // destructor
78 //
80 
81 }
82 
83 
84 //
85 // check if two tracks are compatible with the *tight* criteria
86 //
87 bool
89  const TrackCand& track) const {
90 
91  std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair
92  = convertToTSOSMuHit(sta,track);
93 
94  double chi2 = match_Chi2(tsosPair.first,tsosPair.second);
95  if ( chi2 > 0. && chi2 < theChi2_2 ) return true;
96 
97  double distance = match_d(tsosPair.first,tsosPair.second);
98  if ( distance > 0. && distance < theDeltaD_2 ) return true;
99 
100  //double deltaR = match_Rpos(tsosPair.first,tsosPair.second);
101  //if ( deltaR > 0. && deltaR < theDeltaR_3 ) return true;
102 
103  return false;
104 
105 }
106 
107 
108 //
109 // check if two tracks are compatible
110 //
111 double
113  const TrackCand& track,
114  int matchOption,
115  int surfaceOption) const {
116 
117  std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair;
118  if ( surfaceOption == 0 ) tsosPair = convertToTSOSMuHit(sta,track);
119  if ( surfaceOption == 1 ) tsosPair = convertToTSOSTkHit(sta,track);
120  if ( surfaceOption != 0 && surfaceOption != 1 ) return -1.0;
121 
122  if ( matchOption == 0 ) {
123  // chi^2
124  return match_Chi2(tsosPair.first,tsosPair.second);
125  }
126  else if ( matchOption == 1 ) {
127  // distance
128  return match_d(tsosPair.first,tsosPair.second);
129  }
130  else if ( matchOption == 2 ) {
131  // deltaR
132  return match_Rpos(tsosPair.first,tsosPair.second);
133  }
134  else if ( matchOption == 3 ) {
135  return match_dist(tsosPair.first,tsosPair.second);
136  }
137  else {
138  return -1.0;
139  }
140 }
141 
142 
143 //
144 // choose the track from a TrackCollection which best
145 // matches a given standalone muon track
146 //
147 std::vector<GlobalMuonTrackMatcher::TrackCand>::const_iterator
149  const std::vector<TrackCand>& tracks) const {
150 
151  if ( tracks.empty() ) return tracks.end();
152 
153  double minChi2 = 1000.0;
154  vector<TrackCand>::const_iterator result = tracks.end();
155  for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is) {
156  // propagate to common surface
157  std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair
158  = convertToTSOSMuHit(sta,*is);
159 
160  // calculate chi^2 of local track parameters
161  double chi2 = match_Chi2(tsosPair.first,tsosPair.second);
162  if ( chi2 > 0. && chi2 <= minChi2 ) {
163  minChi2 = chi2;
164  result = is;
165  }
166 
167  }
168 
169  return result;
170 
171 }
172 
173 
174 //
175 // choose a vector of tracks from a TrackCollection that are compatible
176 // with a given standalone track. The order of checks for compatability
177 // * for low momentum: use chi2 selection
178 // * high momentum: use direction or local position
179 //
180 vector<GlobalMuonTrackMatcher::TrackCand>
182  const vector<TrackCand>& tracks) const {
183  const string category = "GlobalMuonTrackMatcher";
184 
185  vector<TrackCand> result;
186 
187  if ( tracks.empty() ) return result;
188 
189  typedef std::pair<TrackCand, TrajectoryStateOnSurface> TrackCandWithTSOS;
190  vector<TrackCandWithTSOS> cands;
191  int iiTk = 1;
192  TrajectoryStateOnSurface muonTSOS;
193 
194  LogTrace(category) << " ***" << endl << "STA Muon pT "<< sta.second->pt();
195  LogTrace(category) << " Tk in Region " << tracks.size() << endl;
196 
197  for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is,iiTk++) {
198  // propagate to a common surface
199  std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair = convertToTSOSMuHit(sta,*is);
200  LogTrace(category) << " Tk " << iiTk << " of " << tracks.size() << " ConvertToMuHitSurface muon isValid " << tsosPair.first.isValid() << " tk isValid " << tsosPair.second.isValid() << endl;
201  if(tsosPair.first.isValid()) muonTSOS = tsosPair.first;
202  cands.push_back(TrackCandWithTSOS(*is,tsosPair.second));
203  }
204 
205  // initialize variables
206  double min_chisq = 999999;
207  double min_d = 999999;
208  double min_de= 999999;
209  double min_r_pos = 999999;
210  std::vector<bool> passes(cands.size(),false);
211  int jj=0;
212 
213  int iTkCand = 1;
214  for (vector<TrackCandWithTSOS>::const_iterator ii = cands.begin(); ii != cands.end(); ++ii,jj++,iTkCand++) {
215 
216  // tracks that are able not able propagate to a common surface
217  if(!muonTSOS.isValid() || !(*ii).second.isValid()) continue;
218 
219  // calculate matching variables
220  double distance = match_d(muonTSOS,(*ii).second);
221  double chi2 = match_Chi2(muonTSOS,(*ii).second);
222  double loc_chi2 = match_dist(muonTSOS,(*ii).second);
223  double deltaR = match_Rpos(muonTSOS,(*ii).second);
224 
225  LogTrace(category) << " iTk " << iTkCand << " of " << cands.size() << " eta " << (*ii).second.globalPosition().eta() << " phi " << (*ii).second.globalPosition().phi() << endl;
226  LogTrace(category) << " distance " << distance << " distance cut " << " " << endl;
227  LogTrace(category) << " chi2 " << chi2 << " chi2 cut " << " " << endl;
228  LogTrace(category) << " loc_chi2 " << loc_chi2 << " locChi2 cut " << " " << endl;
229  LogTrace(category) << " deltaR " << deltaR << " deltaR cut " << " " << endl;
230 
231  if( (*ii).second.globalMomentum().perp()<thePt_threshold1){
232  LogTrace(category) << " Enters a1" << endl;
233 
234  if( ( chi2>0 && fabs((*ii).second.globalMomentum().eta())<theEta_threshold && chi2<theChi2_1 ) || (distance>0 && distance/(*ii).first.second->pt()<theDeltaD_1 && loc_chi2>0 && loc_chi2<theLocChi2) ){
235  LogTrace(category) << " Passes a1" << endl;
236  result.push_back((*ii).first);
237  passes[jj]=true;
238  }
239  }
240  if( (passes[jj]==false) && (*ii).second.globalMomentum().perp()<thePt_threshold2){
241  LogTrace(category) << " Enters a2" << endl;
242  if( ( chi2>0 && chi2< theChi2_2 ) || (distance>0 && distance<theDeltaD_2) ){
243  LogTrace(category) << " Passes a2" << endl;
244  result.push_back((*ii).first);
245  passes[jj] = true;
246  }
247  }else{
248  LogTrace(category) << " Enters a3" << endl;
249  if( distance>0 && distance<theDeltaD_3 && deltaR>0 && deltaR<theDeltaR_1){
250  LogTrace(category) << " Passes a3" << endl;
251  result.push_back((*ii).first);
252  passes[jj]=true;
253  }
254  }
255 
256  if(passes[jj]){
257  if(distance<min_d) min_d = distance;
258  if(loc_chi2<min_de) min_de = loc_chi2;
259  if(deltaR<min_r_pos) min_r_pos = deltaR;
260  if(chi2<min_chisq) min_chisq = chi2;
261  }
262 
263  }
264 
265  // re-initialize mask counter
266  jj=0;
267 
268  if ( result.empty() ) {
269  LogTrace(category) << " Stage 1 returned 0 results";
270  for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is,jj++) {
271  double deltaR = match_Rpos(muonTSOS,(*is).second);
272 
273  if (muonTSOS.isValid() && (*is).second.isValid()) {
274  // check matching between tracker and muon tracks using dEta cut looser then dPhi cut
275  LogTrace(category) << " Stage 2 deltaR " << deltaR << " deltaEta " << fabs((*is).second.globalPosition().eta()-muonTSOS.globalPosition().eta()<1.5*theDeltaR_2) << " deltaPhi " << (fabs(deltaPhi((*is).second.globalPosition().barePhi(),muonTSOS.globalPosition().barePhi()))<theDeltaR_2) << endl;
276 
277  if(fabs((*is).second.globalPosition().eta()-muonTSOS.globalPosition().eta())<1.5*theDeltaR_2
278  &&fabs(deltaPhi((*is).second.globalPosition().barePhi(),muonTSOS.globalPosition().barePhi()))<theDeltaR_2){
279  result.push_back((*is).first);
280  passes[jj]=true;
281  }
282  }
283 
284  if(passes[jj]){
285  double distance = match_d(muonTSOS,(*is).second);
286  double chi2 = match_Chi2(muonTSOS,(*is).second);
287  double loc_chi2 = match_dist(muonTSOS,(*is).second);
288  if(distance<min_d) min_d = distance;
289  if(loc_chi2<min_de) min_de = loc_chi2;
290  if(deltaR<min_r_pos) min_r_pos = deltaR;
291  if(chi2<min_chisq) min_chisq = chi2;
292 
293  }
294 
295  }
296 
297  }
298 
299  for(vector<TrackCand>::const_iterator iTk=result.begin();
300  iTk != result.end(); ++iTk) {
301  LogTrace(category) << " -----" << endl
302  << "selected pt " << iTk->second->pt()
303  << " eta " << iTk->second->eta()
304  << " phi " << iTk->second->phi() << endl;
305  }
306 
307  if(result.size()<2)
308  return result;
309  else
310  result.clear();
311 
312  LogTrace(category) << " Cleaning matched candiates" << endl;
313 
314  // re-initialize mask counter
315  jj=0;
316 
317 
318  for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is,jj++) {
319 
320  if(!passes[jj]) continue;
321 
322  double distance = match_d(muonTSOS,(*is).second);
323  double chi2 = match_Chi2(muonTSOS,(*is).second);
324  //unused double loc_chi2 = match_dist(muonTSOS,(*is).second);
325  double deltaR = match_Rpos(muonTSOS,(*is).second);
326 
327  // compute quality as the relative ratio to the minimum found for each variable
328 
329  int qual = (int)(chi2/min_chisq + distance/min_d + deltaR/min_r_pos);
330  int n_min = ((chi2/min_chisq==1)?1:0) + ((distance/min_d==1)?1:0) + ((deltaR/min_r_pos==1)?1:0);
331 
332  if(n_min == 3){
333  result.push_back((*is).first);
334  }
335 
336  if(n_min == 2 && qual < theQual_1 ){
337  result.push_back((*is).first);
338  }
339 
340  if(n_min == 1 && qual < theQual_2 ){
341  result.push_back((*is).first);
342  }
343 
344  if(n_min == 0 && qual < theQual_3 ){
345  result.push_back((*is).first);
346  }
347 
348  }
349 
350  for(vector<TrackCand>::const_iterator iTk=result.begin();
351  iTk != result.end(); ++iTk) {
352  LogTrace(category) << " -----" << endl
353  << "selected pt " << iTk->second->pt()
354  << " eta " << iTk->second->eta()
355  << " phi " << iTk->second->phi() << endl;
356  }
357 
358  return result;
359 }
360 
361 
362 //
363 // propagate the two track candidates to the tracker bound surface
364 //
365 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
367  const TrackCand& tkCand) const {
368 
369  const string category = "GlobalMuonTrackMatcher";
370 
372 
373  TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
374  TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
375 
376  TrajectoryStateOnSurface outerTkTsos;
377  if (tkCand.second.isNonnull()) {
378  // make sure the tracker track has enough momentum to reach the muon chambers
379  if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt )) {
380 
381  outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
382  }
383  }
384 
385  if ( !impactMuTSOS.isValid() || !outerTkTsos.isValid() ) return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
386 
387  // define StateOnTrackerBound object
388  StateOnTrackerBound fromInside(&*theService->propagator(theOutPropagatorName));
389 
390  // extrapolate to outer tracker surface
391  TrajectoryStateOnSurface tkTsosFromMu = fromInside(impactMuTSOS);
392  TrajectoryStateOnSurface tkTsosFromTk = fromInside(outerTkTsos);
393 
394  if ( !samePlane(tkTsosFromMu,tkTsosFromTk) ) {
395  // propagate tracker track to same surface as muon
396  bool same1, same2;
397  TrajectoryStateOnSurface newTkTsosFromTk, newTkTsosFromMu;
398  if ( tkTsosFromMu.isValid() ) newTkTsosFromTk = theService->propagator(theOutPropagatorName)->propagate(outerTkTsos,tkTsosFromMu.surface());
399  same1 = samePlane(newTkTsosFromTk,tkTsosFromMu);
400  LogTrace(category) << "Propagating to same tracker surface (Mu):" << same1;
401  if ( !same1 ) {
402  if ( tkTsosFromTk.isValid() ) newTkTsosFromMu = theService->propagator(theOutPropagatorName)->propagate(impactMuTSOS,tkTsosFromTk.surface());
403  same2 = samePlane(newTkTsosFromMu,tkTsosFromTk);
404  LogTrace(category) << "Propagating to same tracker surface (Tk):" << same2;
405  }
406  if (same1) tkTsosFromTk = newTkTsosFromTk;
407  else if (same2) tkTsosFromMu = newTkTsosFromMu;
408  else {
409  LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker bound!";
410  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty, empty);
411  }
412  }
413 
414  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(tkTsosFromMu, tkTsosFromTk);
415 
416 }
417 
418 
419 //
420 // propagate the two track candidates to the surface of the innermost muon hit
421 //
422 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
424  const TrackCand& tkCand) const {
425 
426  const string category = "GlobalMuonTrackMatcher";
428  TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
429  TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
430  TrajectoryStateOnSurface outerTkTsos,innerTkTsos;
431  if ( tkCand.second.isNonnull() ) {
432  // make sure the tracker track has enough momentum to reach the muon chambers
433  if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt ) ) {
434  TrajectoryStateOnSurface innerTkTsos;
435 
436  outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
437  innerTkTsos = trajectoryStateTransform::innerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
438  // for cosmics, outer-most referst to last traversed layer
439  if ( (innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() > (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag() )
440  outerTkTsos = innerTkTsos;
441 
442  }
443  }
444 
445  if ( !innerMuTSOS.isValid() || !outerTkTsos.isValid() ) {
446  LogTrace(category) << "A TSOS validity problem! MuTSOS " << innerMuTSOS.isValid() << " TkTSOS " << outerTkTsos.isValid();
447  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
448  }
449 
450  const Surface& refSurface = innerMuTSOS.surface();
451  TrajectoryStateOnSurface tkAtMu = theService->propagator(theOutPropagatorName)->propagate(*outerTkTsos.freeState(),refSurface);
452 
453  if ( !tkAtMu.isValid() ) {
454  LogTrace(category) << "Could not propagate Muon and Tracker track to the same muon hit surface!";
455  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
456  }
457 
458  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(innerMuTSOS, tkAtMu);
459 
460 }
461 
462 
463 //
464 // propagate the two track candidates to the surface of the outermost tracker hit
465 //
466 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
468  const TrackCand& tkCand) const {
469 
470  const string category = "GlobalMuonTrackMatcher";
471 
473 
474  TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
475  TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
476  TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
477 
478  TrajectoryStateOnSurface outerTkTsos,innerTkTsos;
479  if ( tkCand.second.isNonnull() ) {
480  // make sure the tracker track has enough momentum to reach the muon chambers
481  if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt )) {
482 
483  outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
484  innerTkTsos = trajectoryStateTransform::innerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
485 
486  // for cosmics, outer-most referst to last traversed layer
487  if ( (innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() > (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag() )
488  outerTkTsos = innerTkTsos;
489 
490  }
491  }
492 
493  if ( !impactMuTSOS.isValid() || !outerTkTsos.isValid() ) {
494  LogTrace(category) << "A TSOS validity problem! MuTSOS " << impactMuTSOS.isValid() << " TkTSOS " << outerTkTsos.isValid();
495  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
496  }
497 
498  const Surface& refSurface = outerTkTsos.surface();
499  TrajectoryStateOnSurface muAtTk = theService->propagator(theOutPropagatorName)->propagate(*impactMuTSOS.freeState(),refSurface);
500 
501  if ( !muAtTk.isValid() ) {
502  LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker hit surface!";
503  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
504  }
505 
506  return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(muAtTk, outerTkTsos);
507 
508 }
509 
510 
511 //
512 //
513 //
514 bool
516  const TrajectoryStateOnSurface& tsos2) const {
517 
518  if ( !tsos1.isValid() || !tsos2.isValid() ) return false;
519 
520  if ( fabs(match_D(tsos1,tsos2) - match_d(tsos1,tsos2)) > 0.1 ) return false;
521 
522  const float maxtilt = 0.999;
523  const float maxdist = 0.01; // in cm
524 
525  auto p1(tsos1.surface().tangentPlane(tsos1.localPosition()));
526  auto p2(tsos2.surface().tangentPlane(tsos2.localPosition()));
527 
528  bool returnValue = ( (fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt) || (fabs((p1->toLocal(p2->position())).z()) < maxdist) ) ? true : false;
529 
530  return returnValue;
531 
532 }
533 
534 
535 //
536 // calculate Chi^2 of two trajectory states
537 //
538 double
540  const TrajectoryStateOnSurface& tsos2) const {
541 
542  const string category = "GlobalMuonTrackMatcher";
543  //LogTrace(category) << "match_Chi2 sanity check: " << tsos1.isValid() << " " << tsos2.isValid();
544  if ( !tsos1.isValid() || !tsos2.isValid() ) return -1.;
545 
547  AlgebraicSymMatrix55 m(tsos1.localError().matrix() + tsos2.localError().matrix());
548 
549  //LogTrace(category) << "match_Chi2 vector v " << v;
550 
551  bool ierr = !m.Invert();
552 
553  if ( ierr ) {
554  edm::LogInfo(category) << "Error inverting covariance matrix";
555  return -1;
556  }
557 
558  double est = ROOT::Math::Similarity(v,m);
559 
560  //LogTrace(category) << "Chi2 " << est;
561 
562  return est;
563 
564 }
565 
566 
567 //
568 // calculate Delta_R of two track candidates at the IP
569 //
570 double
572  const TrackCand& tkCand) const {
573 
574  double dR = 99.0;
575  if (tkCand.second.isNonnull()) {
576  dR = (deltaR<double>(staCand.second->eta(),staCand.second->phi(),
577  tkCand.second->eta(),tkCand.second->phi()));
578  }
579 
580  return dR;
581 
582 }
583 
584 
585 //
586 // calculate Delta_R of two trajectory states
587 //
588 double
590  const TrajectoryStateOnSurface& tk) const {
591 
592  if( !sta.isValid() || !tk.isValid() ) return -1;
593  return (deltaR<double>(sta.globalMomentum().eta(),sta.globalMomentum().phi(),
594  tk.globalMomentum().eta(),tk.globalMomentum().phi()));
595 
596 }
597 
598 
599 //
600 // calculate Delta_R of two trajectory states
601 //
602 double
604  const TrajectoryStateOnSurface& tk) const {
605 
606  if ( !sta.isValid() || !tk.isValid() ) return -1;
607  return (deltaR<double>(sta.globalPosition().eta(),sta.globalPosition().phi(),
608  tk.globalPosition().eta(),tk.globalPosition().phi()));
609 
610 }
611 
612 
613 //
614 // calculate the distance in global position of two trajectory states
615 //
616 double
618  const TrajectoryStateOnSurface& tk) const {
619 
620  if ( !sta.isValid() || !tk.isValid() ) return -1;
621  return (sta.globalPosition() - tk.globalPosition()).mag();
622 
623 }
624 
625 
626 //
627 // calculate the distance in local position of two trajectory states
628 //
629 double
631  const TrajectoryStateOnSurface& tk) const {
632 
633  if ( !sta.isValid() || !tk.isValid() ) return -1;
634  return (sta.localPosition() - tk.localPosition()).mag();
635 
636 }
637 
638 
639 //
640 // calculate the chi2 of the distance in local position of two
641 // trajectory states including local errors
642 //
643 double
645  const TrajectoryStateOnSurface& tk) const {
646 
647  const string category = "GlobalMuonTrackMatcher";
648 
649  if ( !sta.isValid() || !tk.isValid() ) return -1;
650 
652  m(0,0) = tk.localError().positionError().xx() + sta.localError().positionError().xx();
653  m(1,0) = m(0,1) = tk.localError().positionError().xy() + sta.localError().positionError().xy();
654  m(1,1) = tk.localError().positionError().yy() + sta.localError().positionError().yy();
655 
657  v[0] = tk.localPosition().x() - sta.localPosition().x();
658  v[1] = tk.localPosition().y() - sta.localPosition().y();
659 
660  if ( !m.Invert() ) {
661  LogTrace(category) << "Error inverting local matrix ";
662  return -1;
663  }
664 
665  return ROOT::Math::Similarity(v,m);
666 
667 }
std::vector< TrackCand >::const_iterator matchOne(const TrackCand &sta, const std::vector< TrackCand > &tracks) const
choose the one tracker track which best matches a muon track
T getParameter(std::string const &) const
float xx() const
Definition: LocalError.h:24
GlobalMuonTrackMatcher(const edm::ParameterSet &, const MuonServiceProxy *)
constructor
virtual ConstReferenceCountingPointer< TangentPlane > tangentPlane(const GlobalPoint &) const =0
const LocalTrajectoryParameters & localParameters() const
TrajectoryStateOnSurface outerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
bool matchTight(const TrackCand &sta, const TrackCand &track) const
check if two tracks are compatible (less than Chi2Cut, DeltaDCut, DeltaRCut)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
T y() const
Definition: PV3DBase.h:63
GlobalPoint globalPosition() const
std::pair< TrajectoryStateOnSurface, TrajectoryStateOnSurface > convertToTSOSTkHit(const TrackCand &, const TrackCand &) const
double match_Rmom(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
double match_R_IP(const TrackCand &, const TrackCand &) const
LocalError positionError() const
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepStd< double, 2, 2 > > AlgebraicMatrix22
std::pair< TrajectoryStateOnSurface, TrajectoryStateOnSurface > convertToTSOSMuHit(const TrackCand &, const TrackCand &) const
T barePhi() const
Definition: PV3DBase.h:68
AlgebraicVector5 vector() const
float xy() const
Definition: LocalError.h:25
const SurfaceType & surface() const
std::pair< TrajectoryStateOnSurface, TrajectoryStateOnSurface > convertToTSOSTk(const TrackCand &, const TrackCand &) const
float yy() const
Definition: LocalError.h:26
FreeTrajectoryState const * freeState(bool withErrors=true) const
double match_d(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
double match_Chi2(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
const AlgebraicSymMatrix55 & matrix() const
const LocalTrajectoryError & localError() const
double match(const TrackCand &sta, const TrackCand &track, int matchOption=0, int surfaceOption=1) const
double match_D(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
double p2[4]
Definition: TauolaWrapper.h:90
#define LogTrace(id)
const MuonServiceProxy * theService
ii
Definition: cuy.py:589
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
ROOT::Math::SVector< double, 5 > AlgebraicVector5
T eta() const
Definition: PV3DBase.h:76
double match_dist(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
fixed size matrix
std::pair< const Trajectory *, reco::TrackRef > TrackCand
double p1[4]
Definition: TauolaWrapper.h:89
double match_Rpos(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
GlobalVector globalMomentum() const
bool samePlane(const TrajectoryStateOnSurface &, const TrajectoryStateOnSurface &) const
T x() const
Definition: PV3DBase.h:62
ROOT::Math::SVector< double, 2 > AlgebraicVector2
virtual ~GlobalMuonTrackMatcher()
destructor
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)