File indexing completed on 2024-04-06 12:26:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonTrackMatcher.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include "FWCore/ServiceRegistry/interface/Service.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0026
0027 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0028 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0029 #include "TrackingTools/GeomPropagators/interface/StateOnTrackerBound.h"
0030 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0031 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0032
0033 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0034
0035 #include "DataFormats/TrackReco/interface/Track.h"
0036 #include "DataFormats/TrajectoryState/interface/LocalTrajectoryParameters.h"
0037
0038 #include "DataFormats/GeometrySurface/interface/TangentPlane.h"
0039 #include "DataFormats/Math/interface/deltaR.h"
0040
0041 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0042
0043 using namespace std;
0044 using namespace reco;
0045
0046
0047
0048
0049 GlobalMuonTrackMatcher::GlobalMuonTrackMatcher(const edm::ParameterSet& par, const MuonServiceProxy* service)
0050 : theService(service) {
0051 theMinP = par.getParameter<double>("MinP");
0052 theMinPt = par.getParameter<double>("MinPt");
0053 thePt_threshold1 = par.getParameter<double>("Pt_threshold1");
0054 thePt_threshold2 = par.getParameter<double>("Pt_threshold2");
0055 theEta_threshold = par.getParameter<double>("Eta_threshold");
0056 theChi2_1 = par.getParameter<double>("Chi2Cut_1");
0057 theChi2_2 = par.getParameter<double>("Chi2Cut_2");
0058 theChi2_3 = par.getParameter<double>("Chi2Cut_3");
0059 theLocChi2 = par.getParameter<double>("LocChi2Cut");
0060 theDeltaD_1 = par.getParameter<double>("DeltaDCut_1");
0061 theDeltaD_2 = par.getParameter<double>("DeltaDCut_2");
0062 theDeltaD_3 = par.getParameter<double>("DeltaDCut_3");
0063 theDeltaR_1 = par.getParameter<double>("DeltaRCut_1");
0064 theDeltaR_2 = par.getParameter<double>("DeltaRCut_2");
0065 theDeltaR_3 = par.getParameter<double>("DeltaRCut_3");
0066 theQual_1 = par.getParameter<double>("Quality_1");
0067 theQual_2 = par.getParameter<double>("Quality_2");
0068 theQual_3 = par.getParameter<double>("Quality_3");
0069 theOutPropagatorName = par.getParameter<string>("Propagator");
0070 }
0071
0072
0073
0074
0075 GlobalMuonTrackMatcher::~GlobalMuonTrackMatcher() {}
0076
0077
0078
0079
0080 bool GlobalMuonTrackMatcher::matchTight(const TrackCand& sta, const TrackCand& track) const {
0081 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair = convertToTSOSMuHit(sta, track);
0082
0083 double chi2 = match_Chi2(tsosPair.first, tsosPair.second);
0084 if (chi2 > 0. && chi2 < theChi2_2)
0085 return true;
0086
0087 double distance = match_d(tsosPair.first, tsosPair.second);
0088 if (distance > 0. && distance < theDeltaD_2)
0089 return true;
0090
0091
0092
0093
0094 return false;
0095 }
0096
0097
0098
0099
0100 double GlobalMuonTrackMatcher::match(const TrackCand& sta,
0101 const TrackCand& track,
0102 int matchOption,
0103 int surfaceOption) const {
0104 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair;
0105 if (surfaceOption == 0)
0106 tsosPair = convertToTSOSMuHit(sta, track);
0107 if (surfaceOption == 1)
0108 tsosPair = convertToTSOSTkHit(sta, track);
0109 if (surfaceOption != 0 && surfaceOption != 1)
0110 return -1.0;
0111
0112 if (matchOption == 0) {
0113
0114 return match_Chi2(tsosPair.first, tsosPair.second);
0115 } else if (matchOption == 1) {
0116
0117 return match_d(tsosPair.first, tsosPair.second);
0118 } else if (matchOption == 2) {
0119
0120 return match_Rpos(tsosPair.first, tsosPair.second);
0121 } else if (matchOption == 3) {
0122 return match_dist(tsosPair.first, tsosPair.second);
0123 } else {
0124 return -1.0;
0125 }
0126 }
0127
0128
0129
0130
0131
0132 std::vector<GlobalMuonTrackMatcher::TrackCand>::const_iterator GlobalMuonTrackMatcher::matchOne(
0133 const TrackCand& sta, const std::vector<TrackCand>& tracks) const {
0134 if (tracks.empty())
0135 return tracks.end();
0136
0137 double minChi2 = 1000.0;
0138 vector<TrackCand>::const_iterator result = tracks.end();
0139 for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is) {
0140
0141 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair = convertToTSOSMuHit(sta, *is);
0142
0143
0144 double chi2 = match_Chi2(tsosPair.first, tsosPair.second);
0145 if (chi2 > 0. && chi2 <= minChi2) {
0146 minChi2 = chi2;
0147 result = is;
0148 }
0149 }
0150
0151 return result;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160 vector<GlobalMuonTrackMatcher::TrackCand> GlobalMuonTrackMatcher::match(const TrackCand& sta,
0161 const vector<TrackCand>& tracks) const {
0162 const string category = "GlobalMuonTrackMatcher";
0163
0164 vector<TrackCand> result;
0165
0166 if (tracks.empty())
0167 return result;
0168
0169 typedef std::pair<TrackCand, TrajectoryStateOnSurface> TrackCandWithTSOS;
0170 vector<TrackCandWithTSOS> cands;
0171 int iiTk = 1;
0172 TrajectoryStateOnSurface muonTSOS;
0173
0174 LogTrace(category) << " ***" << endl << "STA Muon pT " << sta.second->pt();
0175 LogTrace(category) << " Tk in Region " << tracks.size() << endl;
0176
0177 for (vector<TrackCand>::const_iterator is = tracks.begin(); is != tracks.end(); ++is, iiTk++) {
0178
0179 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> tsosPair = convertToTSOSMuHit(sta, *is);
0180 LogTrace(category) << " Tk " << iiTk << " of " << tracks.size() << " ConvertToMuHitSurface muon isValid "
0181 << tsosPair.first.isValid() << " tk isValid " << tsosPair.second.isValid() << endl;
0182 if (tsosPair.first.isValid())
0183 muonTSOS = tsosPair.first;
0184 cands.push_back(TrackCandWithTSOS(*is, tsosPair.second));
0185 }
0186
0187
0188 double min_chisq = 999999;
0189 double min_d = 999999;
0190 double min_de = 999999;
0191 double min_r_pos = 999999;
0192 std::vector<bool> passes(cands.size(), false);
0193 int jj = 0;
0194
0195 int iTkCand = 1;
0196 for (vector<TrackCandWithTSOS>::const_iterator ii = cands.begin(); ii != cands.end(); ++ii, jj++, iTkCand++) {
0197
0198 if (!muonTSOS.isValid() || !(*ii).second.isValid())
0199 continue;
0200
0201
0202 double distance = match_d(muonTSOS, (*ii).second);
0203 double chi2 = match_Chi2(muonTSOS, (*ii).second);
0204 double loc_chi2 = match_dist(muonTSOS, (*ii).second);
0205 double deltaR = match_Rpos(muonTSOS, (*ii).second);
0206
0207 LogTrace(category) << " iTk " << iTkCand << " of " << cands.size() << " eta "
0208 << (*ii).second.globalPosition().eta() << " phi " << (*ii).second.globalPosition().phi() << endl;
0209 LogTrace(category) << " distance " << distance << " distance cut "
0210 << " " << endl;
0211 LogTrace(category) << " chi2 " << chi2 << " chi2 cut "
0212 << " " << endl;
0213 LogTrace(category) << " loc_chi2 " << loc_chi2 << " locChi2 cut "
0214 << " " << endl;
0215 LogTrace(category) << " deltaR " << deltaR << " deltaR cut "
0216 << " " << endl;
0217
0218 if ((*ii).second.globalMomentum().perp() < thePt_threshold1) {
0219 LogTrace(category) << " Enters a1" << endl;
0220
0221 if ((chi2 > 0 && fabs((*ii).second.globalMomentum().eta()) < theEta_threshold && chi2 < theChi2_1) ||
0222 (distance > 0 && distance / (*ii).first.second->pt() < theDeltaD_1 && loc_chi2 > 0 &&
0223 loc_chi2 < theLocChi2)) {
0224 LogTrace(category) << " Passes a1" << endl;
0225 result.push_back((*ii).first);
0226 passes[jj] = true;
0227 }
0228 }
0229 if ((passes[jj] == false) && (*ii).second.globalMomentum().perp() < thePt_threshold2) {
0230 LogTrace(category) << " Enters a2" << endl;
0231 if ((chi2 > 0 && chi2 < theChi2_2) || (distance > 0 && distance < theDeltaD_2)) {
0232 LogTrace(category) << " Passes a2" << endl;
0233 result.push_back((*ii).first);
0234 passes[jj] = true;
0235 }
0236 } else {
0237 LogTrace(category) << " Enters a3" << endl;
0238 if (distance > 0 && distance < theDeltaD_3 && deltaR > 0 && deltaR < theDeltaR_1) {
0239 LogTrace(category) << " Passes a3" << endl;
0240 result.push_back((*ii).first);
0241 passes[jj] = true;
0242 }
0243 }
0244
0245 if (passes[jj]) {
0246 if (distance < min_d)
0247 min_d = distance;
0248 if (loc_chi2 < min_de)
0249 min_de = loc_chi2;
0250 if (deltaR < min_r_pos)
0251 min_r_pos = deltaR;
0252 if (chi2 < min_chisq)
0253 min_chisq = chi2;
0254 }
0255 }
0256
0257
0258 jj = 0;
0259
0260 if (result.empty()) {
0261 LogTrace(category) << " Stage 1 returned 0 results";
0262 for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is, jj++) {
0263 double deltaR = match_Rpos(muonTSOS, (*is).second);
0264
0265 if (muonTSOS.isValid() && (*is).second.isValid()) {
0266
0267 LogTrace(category) << " Stage 2 deltaR " << deltaR << " deltaEta "
0268 << fabs((*is).second.globalPosition().eta() - muonTSOS.globalPosition().eta() <
0269 1.5 * theDeltaR_2)
0270 << " deltaPhi "
0271 << (fabs(deltaPhi((*is).second.globalPosition().barePhi(),
0272 muonTSOS.globalPosition().barePhi())) < theDeltaR_2)
0273 << endl;
0274
0275 if (fabs((*is).second.globalPosition().eta() - muonTSOS.globalPosition().eta()) < 1.5 * theDeltaR_2 &&
0276 fabs(deltaPhi((*is).second.globalPosition().barePhi(), muonTSOS.globalPosition().barePhi())) <
0277 theDeltaR_2) {
0278 result.push_back((*is).first);
0279 passes[jj] = true;
0280 }
0281 }
0282
0283 if (passes[jj]) {
0284 double distance = match_d(muonTSOS, (*is).second);
0285 double chi2 = match_Chi2(muonTSOS, (*is).second);
0286 double loc_chi2 = match_dist(muonTSOS, (*is).second);
0287 if (distance < min_d)
0288 min_d = distance;
0289 if (loc_chi2 < min_de)
0290 min_de = loc_chi2;
0291 if (deltaR < min_r_pos)
0292 min_r_pos = deltaR;
0293 if (chi2 < min_chisq)
0294 min_chisq = chi2;
0295 }
0296 }
0297 }
0298
0299 for (vector<TrackCand>::const_iterator iTk = result.begin(); iTk != result.end(); ++iTk) {
0300 LogTrace(category) << " -----" << endl
0301 << "selected pt " << iTk->second->pt() << " eta " << iTk->second->eta() << " phi "
0302 << iTk->second->phi() << endl;
0303 }
0304
0305 if (result.size() < 2)
0306 return result;
0307 else
0308 result.clear();
0309
0310 LogTrace(category) << " Cleaning matched candiates" << endl;
0311
0312
0313 jj = 0;
0314
0315 for (vector<TrackCandWithTSOS>::const_iterator is = cands.begin(); is != cands.end(); ++is, jj++) {
0316 if (!passes[jj])
0317 continue;
0318
0319 double distance = match_d(muonTSOS, (*is).second);
0320 double chi2 = match_Chi2(muonTSOS, (*is).second);
0321
0322 double deltaR = match_Rpos(muonTSOS, (*is).second);
0323
0324
0325
0326 int qual = (int)(chi2 / min_chisq + distance / min_d + deltaR / min_r_pos);
0327 int n_min =
0328 ((chi2 / min_chisq == 1) ? 1 : 0) + ((distance / min_d == 1) ? 1 : 0) + ((deltaR / min_r_pos == 1) ? 1 : 0);
0329
0330 if (n_min == 3) {
0331 result.push_back((*is).first);
0332 }
0333
0334 if (n_min == 2 && qual < theQual_1) {
0335 result.push_back((*is).first);
0336 }
0337
0338 if (n_min == 1 && qual < theQual_2) {
0339 result.push_back((*is).first);
0340 }
0341
0342 if (n_min == 0 && qual < theQual_3) {
0343 result.push_back((*is).first);
0344 }
0345 }
0346
0347 for (vector<TrackCand>::const_iterator iTk = result.begin(); iTk != result.end(); ++iTk) {
0348 LogTrace(category) << " -----" << endl
0349 << "selected pt " << iTk->second->pt() << " eta " << iTk->second->eta() << " phi "
0350 << iTk->second->phi() << endl;
0351 }
0352
0353 return result;
0354 }
0355
0356
0357
0358
0359 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> GlobalMuonTrackMatcher::convertToTSOSTk(
0360 const TrackCand& staCand, const TrackCand& tkCand) const {
0361 const string category = "GlobalMuonTrackMatcher";
0362
0363 TrajectoryStateOnSurface empty;
0364
0365 TransientTrack muTT(*staCand.second, &*theService->magneticField(), theService->trackingGeometry());
0366 TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
0367
0368 TrajectoryStateOnSurface outerTkTsos;
0369 if (tkCand.second.isNonnull()) {
0370
0371 if (!(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt)) {
0372 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(
0373 *tkCand.second, *theService->trackingGeometry(), &*theService->magneticField());
0374 }
0375 }
0376
0377 if (!impactMuTSOS.isValid() || !outerTkTsos.isValid())
0378 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0379
0380
0381 StateOnTrackerBound fromInside(&*theService->propagator(theOutPropagatorName));
0382
0383
0384 TrajectoryStateOnSurface tkTsosFromMu = fromInside(impactMuTSOS);
0385 TrajectoryStateOnSurface tkTsosFromTk = fromInside(outerTkTsos);
0386
0387 if (!samePlane(tkTsosFromMu, tkTsosFromTk)) {
0388
0389 bool same1, same2;
0390 TrajectoryStateOnSurface newTkTsosFromTk, newTkTsosFromMu;
0391 if (tkTsosFromMu.isValid())
0392 newTkTsosFromTk = theService->propagator(theOutPropagatorName)->propagate(outerTkTsos, tkTsosFromMu.surface());
0393 same1 = samePlane(newTkTsosFromTk, tkTsosFromMu);
0394 LogTrace(category) << "Propagating to same tracker surface (Mu):" << same1;
0395 if (!same1) {
0396 if (tkTsosFromTk.isValid())
0397 newTkTsosFromMu = theService->propagator(theOutPropagatorName)->propagate(impactMuTSOS, tkTsosFromTk.surface());
0398 same2 = samePlane(newTkTsosFromMu, tkTsosFromTk);
0399 LogTrace(category) << "Propagating to same tracker surface (Tk):" << same2;
0400 }
0401 if (same1)
0402 tkTsosFromTk = newTkTsosFromTk;
0403 else if (same2)
0404 tkTsosFromMu = newTkTsosFromMu;
0405 else {
0406 LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker bound!";
0407 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0408 }
0409 }
0410
0411 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(tkTsosFromMu, tkTsosFromTk);
0412 }
0413
0414
0415
0416
0417 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> GlobalMuonTrackMatcher::convertToTSOSMuHit(
0418 const TrackCand& staCand, const TrackCand& tkCand) const {
0419 const string category = "GlobalMuonTrackMatcher";
0420 TrajectoryStateOnSurface empty;
0421 TransientTrack muTT(*staCand.second, &*theService->magneticField(), theService->trackingGeometry());
0422 TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
0423 TrajectoryStateOnSurface outerTkTsos, innerTkTsos;
0424 if (tkCand.second.isNonnull()) {
0425
0426 if (!(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt)) {
0427 TrajectoryStateOnSurface innerTkTsos;
0428
0429 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(
0430 *tkCand.second, *theService->trackingGeometry(), &*theService->magneticField());
0431 innerTkTsos = trajectoryStateTransform::innerStateOnSurface(
0432 *tkCand.second, *theService->trackingGeometry(), &*theService->magneticField());
0433
0434 if ((innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() >
0435 (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag())
0436 outerTkTsos = innerTkTsos;
0437 }
0438 }
0439
0440 if (!innerMuTSOS.isValid() || !outerTkTsos.isValid()) {
0441 LogTrace(category) << "A TSOS validity problem! MuTSOS " << innerMuTSOS.isValid() << " TkTSOS "
0442 << outerTkTsos.isValid();
0443 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0444 }
0445
0446 const Surface& refSurface = innerMuTSOS.surface();
0447 TrajectoryStateOnSurface tkAtMu =
0448 theService->propagator(theOutPropagatorName)->propagate(*outerTkTsos.freeState(), refSurface);
0449
0450 if (!tkAtMu.isValid()) {
0451 LogTrace(category) << "Could not propagate Muon and Tracker track to the same muon hit surface!";
0452 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0453 }
0454
0455 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(innerMuTSOS, tkAtMu);
0456 }
0457
0458
0459
0460
0461 std::pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface> GlobalMuonTrackMatcher::convertToTSOSTkHit(
0462 const TrackCand& staCand, const TrackCand& tkCand) const {
0463 const string category = "GlobalMuonTrackMatcher";
0464
0465 TrajectoryStateOnSurface empty;
0466
0467 TransientTrack muTT(*staCand.second, &*theService->magneticField(), theService->trackingGeometry());
0468 TrajectoryStateOnSurface impactMuTSOS = muTT.impactPointState();
0469 TrajectoryStateOnSurface innerMuTSOS = muTT.innermostMeasurementState();
0470
0471 TrajectoryStateOnSurface outerTkTsos, innerTkTsos;
0472 if (tkCand.second.isNonnull()) {
0473
0474 if (!(tkCand.second->p() < theMinP || tkCand.second->pt() < theMinPt)) {
0475 outerTkTsos = trajectoryStateTransform::outerStateOnSurface(
0476 *tkCand.second, *theService->trackingGeometry(), &*theService->magneticField());
0477 innerTkTsos = trajectoryStateTransform::innerStateOnSurface(
0478 *tkCand.second, *theService->trackingGeometry(), &*theService->magneticField());
0479
0480
0481 if ((innerMuTSOS.globalPosition() - outerTkTsos.globalPosition()).mag() >
0482 (innerMuTSOS.globalPosition() - innerTkTsos.globalPosition()).mag())
0483 outerTkTsos = innerTkTsos;
0484 }
0485 }
0486
0487 if (!impactMuTSOS.isValid() || !outerTkTsos.isValid()) {
0488 LogTrace(category) << "A TSOS validity problem! MuTSOS " << impactMuTSOS.isValid() << " TkTSOS "
0489 << outerTkTsos.isValid();
0490 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0491 }
0492
0493 const Surface& refSurface = outerTkTsos.surface();
0494 TrajectoryStateOnSurface muAtTk =
0495 theService->propagator(theOutPropagatorName)->propagate(*impactMuTSOS.freeState(), refSurface);
0496
0497 if (!muAtTk.isValid()) {
0498 LogTrace(category) << "Could not propagate Muon and Tracker track to the same tracker hit surface!";
0499 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(empty, empty);
0500 }
0501
0502 return pair<TrajectoryStateOnSurface, TrajectoryStateOnSurface>(muAtTk, outerTkTsos);
0503 }
0504
0505
0506
0507
0508 bool GlobalMuonTrackMatcher::samePlane(const TrajectoryStateOnSurface& tsos1,
0509 const TrajectoryStateOnSurface& tsos2) const {
0510 if (!tsos1.isValid() || !tsos2.isValid())
0511 return false;
0512
0513 if (fabs(match_D(tsos1, tsos2) - match_d(tsos1, tsos2)) > 0.1)
0514 return false;
0515
0516 const float maxtilt = 0.999;
0517 const float maxdist = 0.01;
0518
0519 auto p1(tsos1.surface().tangentPlane(tsos1.localPosition()));
0520 auto p2(tsos2.surface().tangentPlane(tsos2.localPosition()));
0521
0522 bool returnValue = ((fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt) ||
0523 (fabs((p1->toLocal(p2->position())).z()) < maxdist))
0524 ? true
0525 : false;
0526
0527 return returnValue;
0528 }
0529
0530
0531
0532
0533 double GlobalMuonTrackMatcher::match_Chi2(const TrajectoryStateOnSurface& tsos1,
0534 const TrajectoryStateOnSurface& tsos2) const {
0535 const string category = "GlobalMuonTrackMatcher";
0536
0537 if (!tsos1.isValid() || !tsos2.isValid())
0538 return -1.;
0539
0540 AlgebraicVector5 v(tsos1.localParameters().vector() - tsos2.localParameters().vector());
0541 AlgebraicSymMatrix55 m(tsos1.localError().matrix() + tsos2.localError().matrix());
0542
0543
0544
0545 bool ierr = !m.Invert();
0546
0547 if (ierr) {
0548 edm::LogInfo(category) << "Error inverting covariance matrix";
0549 return -1;
0550 }
0551
0552 double est = ROOT::Math::Similarity(v, m);
0553
0554
0555
0556 return est;
0557 }
0558
0559
0560
0561
0562 double GlobalMuonTrackMatcher::match_R_IP(const TrackCand& staCand, const TrackCand& tkCand) const {
0563 double dR = 99.0;
0564 if (tkCand.second.isNonnull()) {
0565 dR = (deltaR<double>(staCand.second->eta(), staCand.second->phi(), tkCand.second->eta(), tkCand.second->phi()));
0566 }
0567
0568 return dR;
0569 }
0570
0571
0572
0573
0574 double GlobalMuonTrackMatcher::match_Rmom(const TrajectoryStateOnSurface& sta,
0575 const TrajectoryStateOnSurface& tk) const {
0576 if (!sta.isValid() || !tk.isValid())
0577 return -1;
0578 return (deltaR<double>(
0579 sta.globalMomentum().eta(), sta.globalMomentum().phi(), tk.globalMomentum().eta(), tk.globalMomentum().phi()));
0580 }
0581
0582
0583
0584
0585 double GlobalMuonTrackMatcher::match_Rpos(const TrajectoryStateOnSurface& sta,
0586 const TrajectoryStateOnSurface& tk) const {
0587 if (!sta.isValid() || !tk.isValid())
0588 return -1;
0589 return (deltaR<double>(
0590 sta.globalPosition().eta(), sta.globalPosition().phi(), tk.globalPosition().eta(), tk.globalPosition().phi()));
0591 }
0592
0593
0594
0595
0596 double GlobalMuonTrackMatcher::match_D(const TrajectoryStateOnSurface& sta, const TrajectoryStateOnSurface& tk) const {
0597 if (!sta.isValid() || !tk.isValid())
0598 return -1;
0599 return (sta.globalPosition() - tk.globalPosition()).mag();
0600 }
0601
0602
0603
0604
0605 double GlobalMuonTrackMatcher::match_d(const TrajectoryStateOnSurface& sta, const TrajectoryStateOnSurface& tk) const {
0606 if (!sta.isValid() || !tk.isValid())
0607 return -1;
0608 return (sta.localPosition() - tk.localPosition()).mag();
0609 }
0610
0611
0612
0613
0614
0615 double GlobalMuonTrackMatcher::match_dist(const TrajectoryStateOnSurface& sta,
0616 const TrajectoryStateOnSurface& tk) const {
0617 const string category = "GlobalMuonTrackMatcher";
0618
0619 if (!sta.isValid() || !tk.isValid())
0620 return -1;
0621
0622 AlgebraicMatrix22 m;
0623 m(0, 0) = tk.localError().positionError().xx() + sta.localError().positionError().xx();
0624 m(1, 0) = m(0, 1) = tk.localError().positionError().xy() + sta.localError().positionError().xy();
0625 m(1, 1) = tk.localError().positionError().yy() + sta.localError().positionError().yy();
0626
0627 AlgebraicVector2 v;
0628 v[0] = tk.localPosition().x() - sta.localPosition().x();
0629 v[1] = tk.localPosition().y() - sta.localPosition().y();
0630
0631 if (!m.Invert()) {
0632 LogTrace(category) << "Error inverting local matrix ";
0633 return -1;
0634 }
0635
0636 return ROOT::Math::Similarity(v, m);
0637 }