00001
00015 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonTrackMatcher.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "FWCore/ServiceRegistry/interface/Service.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029
00030 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00031 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00032 #include "TrackingTools/GeomPropagators/interface/StateOnTrackerBound.h"
00033 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00034 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00035
00036 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00037
00038 #include "DataFormats/TrackReco/interface/Track.h"
00039 #include "DataFormats/TrajectoryState/interface/LocalTrajectoryParameters.h"
00040
00041 #include "DataFormats/GeometrySurface/interface/TangentPlane.h"
00042 #include "DataFormats/Math/interface/deltaR.h"
00043
00044 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00045
00046 using namespace std;
00047 using namespace reco;
00048
00049
00050
00051
00052 GlobalMuonTrackMatcher::GlobalMuonTrackMatcher(const edm::ParameterSet& par,
00053 const MuonServiceProxy* service) :
00054 theService(service) {
00055 theMinP = par.getParameter<double>("MinP");
00056 theMinPt = par.getParameter<double>("MinPt");
00057 thePt_threshold1 = par.getParameter<double>("Pt_threshold1");
00058 thePt_threshold2 = par.getParameter<double>("Pt_threshold2");
00059 theEta_threshold= par.getParameter<double>("Eta_threshold");
00060 theChi2_1= par.getParameter<double>("Chi2Cut_1");
00061 theChi2_2= par.getParameter<double>("Chi2Cut_2");
00062 theChi2_3= par.getParameter<double>("Chi2Cut_3");
00063 theLocChi2= par.getParameter<double>("LocChi2Cut");
00064 theDeltaD_1= par.getParameter<double>("DeltaDCut_1");
00065 theDeltaD_2= par.getParameter<double>("DeltaDCut_2");
00066 theDeltaD_3= par.getParameter<double>("DeltaDCut_3");
00067 theDeltaR_1= par.getParameter<double>("DeltaRCut_1");
00068 theDeltaR_2= par.getParameter<double>("DeltaRCut_2");
00069 theDeltaR_3= par.getParameter<double>("DeltaRCut_3");
00070 theQual_1= par.getParameter<double>("Quality_1");
00071 theQual_2= par.getParameter<double>("Quality_2");
00072 theQual_3= par.getParameter<double>("Quality_3");
00073 theOutPropagatorName = par.getParameter<string>("Propagator");
00074
00075 }
00076
00077
00078
00079
00080
00081 GlobalMuonTrackMatcher::~GlobalMuonTrackMatcher() {
00082
00083 }
00084
00085
00086
00087
00088
00089 bool
00090 GlobalMuonTrackMatcher::matchTight(const TrackCand& sta,
00091 const TrackCand& track) const {
00092
00093 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair
00094 = convertToTSOSMuHit(sta,track);
00095
00096 double chi2 = match_Chi2(tsosPair.first,tsosPair.second);
00097 if ( chi2 > 0. && chi2 < theChi2_2 ) return true;
00098
00099 double distance = match_d(tsosPair.first,tsosPair.second);
00100 if ( distance > 0. && distance < theDeltaD_2 ) return true;
00101
00102
00103
00104
00105 return false;
00106
00107 }
00108
00109
00110
00111
00112
00113 double
00114 GlobalMuonTrackMatcher::match(const TrackCand& sta,
00115 const TrackCand& track,
00116 int matchOption,
00117 int surfaceOption) const {
00118
00119 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair;
00120 if ( surfaceOption == 0 ) tsosPair = convertToTSOSMuHit(sta,track);
00121 if ( surfaceOption == 1 ) tsosPair = convertToTSOSTkHit(sta,track);
00122 if ( surfaceOption != 0 && surfaceOption != 1 ) return -1.0;
00123
00124 if ( matchOption == 0 ) {
00125
00126 return match_Chi2(tsosPair.first,tsosPair.second);
00127 }
00128 else if ( matchOption == 1 ) {
00129
00130 return match_d(tsosPair.first,tsosPair.second);
00131 }
00132 else if ( matchOption == 2 ) {
00133
00134 return match_Rpos(tsosPair.first,tsosPair.second);
00135 }
00136 else if ( matchOption == 3 ) {
00137 return match_dist(tsosPair.first,tsosPair.second);
00138 }
00139 else {
00140 return -1.0;
00141 }
00142 }
00143
00144
00145
00146
00147
00148
00149 std::vector<GlobalMuonTrackMatcher::TrackCand>::const_iterator
00150 GlobalMuonTrackMatcher::matchOne(const TrackCand& sta,
00151 const std::vector<TrackCand>& tracks) const {
00152
00153 if ( tracks.empty() ) return tracks.end();
00154
00155 double minChi2 = 1000.0;
00156 vector<TrackCand>::const_iterator result = tracks.end();
00157 for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is) {
00158
00159 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair
00160 = convertToTSOSMuHit(sta,*is);
00161
00162
00163 double chi2 = match_Chi2(tsosPair.first,tsosPair.second);
00164 if ( chi2 > 0. && chi2 <= minChi2 ) {
00165 minChi2 = chi2;
00166 result = is;
00167 }
00168
00169 }
00170
00171 return result;
00172
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182 vector<GlobalMuonTrackMatcher::TrackCand>
00183 GlobalMuonTrackMatcher::match(const TrackCand& sta,
00184 const vector<TrackCand>& tracks) const {
00185 const string category = "GlobalMuonTrackMatcher";
00186
00187 vector<TrackCand> result;
00188
00189 if ( tracks.empty() ) return result;
00190
00191 typedef std::pair<TrackCand, TrajectoryStateOnSurface> TrackCandWithTSOS;
00192 vector<TrackCandWithTSOS> cands;
00193 int iiTk = 1;
00194 TrajectoryStateOnSurface muonTSOS;
00195
00196 LogTrace(category) << " ***" << endl << "STA Muon pT "<< sta.second->pt();
00197 LogTrace(category) << " Tk in Region " << tracks.size() << endl;
00198
00199 for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is,iiTk++) {
00200
00201 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair = convertToTSOSMuHit(sta,*is);
00202 LogTrace(category) << " Tk " << iiTk << " of " << tracks.size() << " ConvertToMuHitSurface muon isValid " << tsosPair.first.isValid() << " tk isValid " << tsosPair.second.isValid() << endl;
00203 if(tsosPair.first.isValid()) muonTSOS = tsosPair.first;
00204 cands.push_back(TrackCandWithTSOS(*is,tsosPair.second));
00205 }
00206
00207
00208 double min_chisq = 999999;
00209 double min_d = 999999;
00210 double min_de= 999999;
00211 double min_r_pos = 999999;
00212 std::vector<bool> passes(cands.size(),false);
00213 int jj=0;
00214
00215 int iTkCand = 1;
00216 for (vector<TrackCandWithTSOS>::const_iterator ii = cands.begin(); ii != cands.end(); ++ii,jj++,iTkCand++) {
00217
00218
00219 if(!muonTSOS.isValid() || !(*ii).second.isValid()) continue;
00220
00221
00222 double distance = match_d(muonTSOS,(*ii).second);
00223 double chi2 = match_Chi2(muonTSOS,(*ii).second);
00224 double loc_chi2 = match_dist(muonTSOS,(*ii).second);
00225 double deltaR = match_Rpos(muonTSOS,(*ii).second);
00226
00227 LogTrace(category) << " iTk " << iTkCand << " of " << cands.size() << " eta " << (*ii).second.globalPosition().eta() << " phi " << (*ii).second.globalPosition().phi() << endl;
00228 LogTrace(category) << " distance " << distance << " distance cut " << " " << endl;
00229 LogTrace(category) << " chi2 " << chi2 << " chi2 cut " << " " << endl;
00230 LogTrace(category) << " loc_chi2 " << loc_chi2 << " locChi2 cut " << " " << endl;
00231 LogTrace(category) << " deltaR " << deltaR << " deltaR cut " << " " << endl;
00232
00233 if( (*ii).second.globalMomentum().perp()<thePt_threshold1){
00234 LogTrace(category) << " Enters a1" << endl;
00235
00236 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) ){
00237 LogTrace(category) << " Passes a1" << endl;
00238 result.push_back((*ii).first);
00239 passes[jj]=true;
00240 }
00241 }
00242 if( (passes[jj]==false) && (*ii).second.globalMomentum().perp()<thePt_threshold2){
00243 LogTrace(category) << " Enters a2" << endl;
00244 if( ( chi2>0 && chi2< theChi2_2 ) || (distance>0 && distance<theDeltaD_2) ){
00245 LogTrace(category) << " Passes a2" << endl;
00246 result.push_back((*ii).first);
00247 passes[jj] = true;
00248 }
00249 }else{
00250 LogTrace(category) << " Enters a3" << endl;
00251 if( distance>0 && distance<theDeltaD_3 && deltaR>0 && deltaR<theDeltaR_1){
00252 LogTrace(category) << " Passes a3" << endl;
00253 result.push_back((*ii).first);
00254 passes[jj]=true;
00255 }
00256 }
00257
00258 if(passes[jj]){
00259 if(distance<min_d) min_d = distance;
00260 if(loc_chi2<min_de) min_de = loc_chi2;
00261 if(deltaR<min_r_pos) min_r_pos = deltaR;
00262 if(chi2<min_chisq) min_chisq = chi2;
00263 }
00264
00265 }
00266
00267
00268 jj=0;
00269
00270 if ( result.empty() ) {
00271 LogTrace(category) << " Stage 1 returned 0 results";
00272 for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is,jj++) {
00273 double deltaR = match_Rpos(muonTSOS,(*is).second);
00274
00275 if (muonTSOS.isValid() && (*is).second.isValid()) {
00276
00277 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().phi(),muonTSOS.globalPosition().phi()))<theDeltaR_2) << endl;
00278
00279 if(fabs((*is).second.globalPosition().eta()-muonTSOS.globalPosition().eta())<1.5*theDeltaR_2
00280 &&fabs(deltaPhi((*is).second.globalPosition().phi(),muonTSOS.globalPosition().phi()))<theDeltaR_2){
00281 result.push_back((*is).first);
00282 passes[jj]=true;
00283 }
00284 }
00285
00286 if(passes[jj]){
00287 double distance = match_d(muonTSOS,(*is).second);
00288 double chi2 = match_Chi2(muonTSOS,(*is).second);
00289 double loc_chi2 = match_dist(muonTSOS,(*is).second);
00290 if(distance<min_d) min_d = distance;
00291 if(loc_chi2<min_de) min_de = loc_chi2;
00292 if(deltaR<min_r_pos) min_r_pos = deltaR;
00293 if(chi2<min_chisq) min_chisq = chi2;
00294
00295 }
00296
00297 }
00298
00299 }
00300
00301 for(vector<TrackCand>::const_iterator iTk=result.begin();
00302 iTk != result.end(); ++iTk) {
00303 LogTrace(category) << " -----" << endl
00304 << "selected pt " << iTk->second->pt()
00305 << " eta " << iTk->second->eta()
00306 << " phi " << iTk->second->phi() << endl;
00307 }
00308
00309 if(result.size()<2)
00310 return result;
00311 else
00312 result.clear();
00313
00314 LogTrace(category) << " Cleaning matched candiates" << endl;
00315
00316
00317 jj=0;
00318
00319
00320 for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is,jj++) {
00321
00322 if(!passes[jj]) continue;
00323
00324 double distance = match_d(muonTSOS,(*is).second);
00325 double chi2 = match_Chi2(muonTSOS,(*is).second);
00326
00327 double deltaR = match_Rpos(muonTSOS,(*is).second);
00328
00329
00330
00331 int qual = (int)(chi2/min_chisq + distance/min_d + deltaR/min_r_pos);
00332 int n_min = ((chi2/min_chisq==1)?1:0) + ((distance/min_d==1)?1:0) + ((deltaR/min_r_pos==1)?1:0);
00333
00334 if(n_min == 3){
00335 result.push_back((*is).first);
00336 }
00337
00338 if(n_min == 2 && qual < theQual_1 ){
00339 result.push_back((*is).first);
00340 }
00341
00342 if(n_min == 1 && qual < theQual_2 ){
00343 result.push_back((*is).first);
00344 }
00345
00346 if(n_min == 0 && qual < theQual_3 ){
00347 result.push_back((*is).first);
00348 }
00349
00350 }
00351
00352 for(vector<TrackCand>::const_iterator iTk=result.begin();
00353 iTk != result.end(); ++iTk) {
00354 LogTrace(category) << " -----" << endl
00355 << "selected pt " << iTk->second->pt()
00356 << " eta " << iTk->second->eta()
00357 << " phi " << iTk->second->phi() << endl;
00358 }
00359
00360 return result;
00361 }
00362
00363
00364
00365
00366
00367 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
00368 GlobalMuonTrackMatcher::convertToTSOSTk(const TrackCand& staCand,
00369 const TrackCand& tkCand) const {
00370
00371 const string category = "GlobalMuonTrackMatcher";
00372
00373 TrajectoryStateOnSurface empty;
00374
00375 TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
00376 TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
00377
00378 TrajectoryStateOnSurface outerTkTsos;
00379 if (tkCand.second.isNonnull()) {
00380
00381 if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt )) {
00382
00383 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
00384 }
00385 }
00386
00387 if ( !impactMuTSOS.isValid() || !outerTkTsos.isValid() ) return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
00388
00389
00390 StateOnTrackerBound fromInside(&*theService->propagator(theOutPropagatorName));
00391
00392
00393 TrajectoryStateOnSurface tkTsosFromMu = fromInside(impactMuTSOS);
00394 TrajectoryStateOnSurface tkTsosFromTk = fromInside(outerTkTsos);
00395
00396 if ( !samePlane(tkTsosFromMu,tkTsosFromTk) ) {
00397
00398 bool same1, same2;
00399 TrajectoryStateOnSurface newTkTsosFromTk, newTkTsosFromMu;
00400 if ( tkTsosFromMu.isValid() ) newTkTsosFromTk = theService->propagator(theOutPropagatorName)->propagate(outerTkTsos,tkTsosFromMu.surface());
00401 same1 = samePlane(newTkTsosFromTk,tkTsosFromMu);
00402 LogTrace(category) << "Propagating to same tracker surface (Mu):" << same1;
00403 if ( !same1 ) {
00404 if ( tkTsosFromTk.isValid() ) newTkTsosFromMu = theService->propagator(theOutPropagatorName)->propagate(impactMuTSOS,tkTsosFromTk.surface());
00405 same2 = samePlane(newTkTsosFromMu,tkTsosFromTk);
00406 LogTrace(category) << "Propagating to same tracker surface (Tk):" << same2;
00407 }
00408 if (same1) tkTsosFromTk = newTkTsosFromTk;
00409 else if (same2) tkTsosFromMu = newTkTsosFromMu;
00410 else {
00411 LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker bound!";
00412 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty, empty);
00413 }
00414 }
00415
00416 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(tkTsosFromMu, tkTsosFromTk);
00417
00418 }
00419
00420
00421
00422
00423
00424 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
00425 GlobalMuonTrackMatcher::convertToTSOSMuHit(const TrackCand& staCand,
00426 const TrackCand& tkCand) const {
00427
00428 const string category = "GlobalMuonTrackMatcher";
00429 TrajectoryStateOnSurface empty;
00430 TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
00431 TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
00432 TrajectoryStateOnSurface outerTkTsos,innerTkTsos;
00433 if ( tkCand.second.isNonnull() ) {
00434
00435 if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt ) ) {
00436 TrajectoryStateOnSurface innerTkTsos;
00437
00438 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
00439 innerTkTsos = trajectoryStateTransform::innerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
00440
00441 if ( (innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() > (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag() )
00442 outerTkTsos = innerTkTsos;
00443
00444 }
00445 }
00446
00447 if ( !innerMuTSOS.isValid() || !outerTkTsos.isValid() ) {
00448 LogTrace(category) << "A TSOS validity problem! MuTSOS " << innerMuTSOS.isValid() << " TkTSOS " << outerTkTsos.isValid();
00449 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
00450 }
00451
00452 const Surface& refSurface = innerMuTSOS.surface();
00453 TrajectoryStateOnSurface tkAtMu = theService->propagator(theOutPropagatorName)->propagate(*outerTkTsos.freeState(),refSurface);
00454
00455 if ( !tkAtMu.isValid() ) {
00456 LogTrace(category) << "Could not propagate Muon and Tracker track to the same muon hit surface!";
00457 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
00458 }
00459
00460 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(innerMuTSOS, tkAtMu);
00461
00462 }
00463
00464
00465
00466
00467
00468 std::pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>
00469 GlobalMuonTrackMatcher::convertToTSOSTkHit(const TrackCand& staCand,
00470 const TrackCand& tkCand) const {
00471
00472 const string category = "GlobalMuonTrackMatcher";
00473
00474 TrajectoryStateOnSurface empty;
00475
00476 TransientTrack muTT(*staCand.second,&*theService->magneticField(),theService->trackingGeometry());
00477 TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
00478 TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
00479
00480 TrajectoryStateOnSurface outerTkTsos,innerTkTsos;
00481 if ( tkCand.second.isNonnull() ) {
00482
00483 if ( !(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt )) {
00484
00485 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
00486 innerTkTsos = trajectoryStateTransform::innerStateOnSurface(*tkCand.second,*theService->trackingGeometry(),&*theService->magneticField());
00487
00488
00489 if ( (innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() > (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag() )
00490 outerTkTsos = innerTkTsos;
00491
00492 }
00493 }
00494
00495 if ( !impactMuTSOS.isValid() || !outerTkTsos.isValid() ) {
00496 LogTrace(category) << "A TSOS validity problem! MuTSOS " << impactMuTSOS.isValid() << " TkTSOS " << outerTkTsos.isValid();
00497 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
00498 }
00499
00500 const Surface& refSurface = outerTkTsos.surface();
00501 TrajectoryStateOnSurface muAtTk = theService->propagator(theOutPropagatorName)->propagate(*impactMuTSOS.freeState(),refSurface);
00502
00503 if ( !muAtTk.isValid() ) {
00504 LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker hit surface!";
00505 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(empty,empty);
00506 }
00507
00508 return pair<TrajectoryStateOnSurface,TrajectoryStateOnSurface>(muAtTk, outerTkTsos);
00509
00510 }
00511
00512
00513
00514
00515
00516 bool
00517 GlobalMuonTrackMatcher::samePlane(const TrajectoryStateOnSurface& tsos1,
00518 const TrajectoryStateOnSurface& tsos2) const {
00519
00520 if ( !tsos1.isValid() || !tsos2.isValid() ) return false;
00521
00522 if ( fabs(match_D(tsos1,tsos2) - match_d(tsos1,tsos2)) > 0.1 ) return false;
00523
00524 const float maxtilt = 0.999;
00525 const float maxdist = 0.01;
00526
00527 ReferenceCountingPointer<TangentPlane> p1(tsos1.surface().tangentPlane(tsos1.localPosition()));
00528 ReferenceCountingPointer<TangentPlane> p2(tsos2.surface().tangentPlane(tsos2.localPosition()));
00529
00530 bool returnValue = ( (fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt) || (fabs((p1->toLocal(p2->position())).z()) < maxdist) ) ? true : false;
00531
00532 return returnValue;
00533
00534 }
00535
00536
00537
00538
00539
00540 double
00541 GlobalMuonTrackMatcher::match_Chi2(const TrajectoryStateOnSurface& tsos1,
00542 const TrajectoryStateOnSurface& tsos2) const {
00543
00544 const string category = "GlobalMuonTrackMatcher";
00545
00546 if ( !tsos1.isValid() || !tsos2.isValid() ) return -1.;
00547
00548 AlgebraicVector5 v(tsos1.localParameters().vector() - tsos2.localParameters().vector());
00549 AlgebraicSymMatrix55 m(tsos1.localError().matrix() + tsos2.localError().matrix());
00550
00551
00552
00553 bool ierr = !m.Invert();
00554
00555 if ( ierr ) {
00556 edm::LogInfo(category) << "Error inverting covariance matrix";
00557 return -1;
00558 }
00559
00560 double est = ROOT::Math::Similarity(v,m);
00561
00562
00563
00564 return est;
00565
00566 }
00567
00568
00569
00570
00571
00572 double
00573 GlobalMuonTrackMatcher::match_R_IP(const TrackCand& staCand,
00574 const TrackCand& tkCand) const {
00575
00576 double dR = 99.0;
00577 if (tkCand.second.isNonnull()) {
00578 dR = (deltaR<double>(staCand.second->eta(),staCand.second->phi(),
00579 tkCand.second->eta(),tkCand.second->phi()));
00580 }
00581
00582 return dR;
00583
00584 }
00585
00586
00587
00588
00589
00590 double
00591 GlobalMuonTrackMatcher::match_Rmom(const TrajectoryStateOnSurface& sta,
00592 const TrajectoryStateOnSurface& tk) const {
00593
00594 if( !sta.isValid() || !tk.isValid() ) return -1;
00595 return (deltaR<double>(sta.globalMomentum().eta(),sta.globalMomentum().phi(),
00596 tk.globalMomentum().eta(),tk.globalMomentum().phi()));
00597
00598 }
00599
00600
00601
00602
00603
00604 double
00605 GlobalMuonTrackMatcher::match_Rpos(const TrajectoryStateOnSurface& sta,
00606 const TrajectoryStateOnSurface& tk) const {
00607
00608 if ( !sta.isValid() || !tk.isValid() ) return -1;
00609 return (deltaR<double>(sta.globalPosition().eta(),sta.globalPosition().phi(),
00610 tk.globalPosition().eta(),tk.globalPosition().phi()));
00611
00612 }
00613
00614
00615
00616
00617
00618 double
00619 GlobalMuonTrackMatcher::match_D(const TrajectoryStateOnSurface& sta,
00620 const TrajectoryStateOnSurface& tk) const {
00621
00622 if ( !sta.isValid() || !tk.isValid() ) return -1;
00623 return (sta.globalPosition() - tk.globalPosition()).mag();
00624
00625 }
00626
00627
00628
00629
00630
00631 double
00632 GlobalMuonTrackMatcher::match_d(const TrajectoryStateOnSurface& sta,
00633 const TrajectoryStateOnSurface& tk) const {
00634
00635 if ( !sta.isValid() || !tk.isValid() ) return -1;
00636 return (sta.localPosition() - tk.localPosition()).mag();
00637
00638 }
00639
00640
00641
00642
00643
00644
00645 double
00646 GlobalMuonTrackMatcher::match_dist(const TrajectoryStateOnSurface& sta,
00647 const TrajectoryStateOnSurface& tk) const {
00648
00649 const string category = "GlobalMuonTrackMatcher";
00650
00651 if ( !sta.isValid() || !tk.isValid() ) return -1;
00652
00653 AlgebraicMatrix22 m;
00654 m(0,0) = tk.localError().positionError().xx() + sta.localError().positionError().xx();
00655 m(1,0) = m(0,1) = tk.localError().positionError().xy() + sta.localError().positionError().xy();
00656 m(1,1) = tk.localError().positionError().yy() + sta.localError().positionError().yy();
00657
00658 AlgebraicVector2 v;
00659 v[0] = tk.localPosition().x() - sta.localPosition().x();
00660 v[1] = tk.localPosition().y() - sta.localPosition().y();
00661
00662 if ( !m.Invert() ) {
00663 LogTrace(category) << "Error inverting local matrix ";
00664 return -1;
00665 }
00666
00667 return ROOT::Math::Similarity(v,m);
00668
00669 }