00001 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00002 #include "DataFormats/TrackReco/interface/Track.h"
00003 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00004 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00005 #include "DataFormats/VertexReco/interface/Vertex.h"
00006 #include "DataFormats/MuonReco/interface/MuonCocktails.h"
00007 namespace muon {
00008 SelectionType selectionTypeFromString( const std::string &label )
00009 {
00010 static SelectionTypeStringToEnum selectionTypeStringToEnumMap[] = {
00011 { "All", All },
00012 { "AllGlobalMuons", AllGlobalMuons },
00013 { "AllStandAloneMuons", AllStandAloneMuons },
00014 { "AllTrackerMuons", AllTrackerMuons },
00015 { "TrackerMuonArbitrated", TrackerMuonArbitrated },
00016 { "AllArbitrated", AllArbitrated },
00017 { "GlobalMuonPromptTight", GlobalMuonPromptTight },
00018 { "TMLastStationLoose", TMLastStationLoose },
00019 { "TMLastStationTight", TMLastStationTight },
00020 { "TM2DCompatibilityLoose", TM2DCompatibilityLoose },
00021 { "TM2DCompatibilityTight", TM2DCompatibilityTight },
00022 { "TMOneStationLoose", TMOneStationLoose },
00023 { "TMOneStationTight", TMOneStationTight },
00024 { "TMLastStationOptimizedLowPtLoose", TMLastStationOptimizedLowPtLoose },
00025 { "TMLastStationOptimizedLowPtTight", TMLastStationOptimizedLowPtTight },
00026 { "GMTkChiCompatibility", GMTkChiCompatibility },
00027 { "GMStaChiCompatibility", GMStaChiCompatibility},
00028 { "GMTkKinkTight", GMTkKinkTight},
00029 { "TMLastStationAngLoose", TMLastStationAngLoose },
00030 { "TMLastStationAngTight", TMLastStationAngTight },
00031 { "TMOneStationAngLoose", TMOneStationAngLoose },
00032 { "TMOneStationAngTight", TMOneStationAngTight },
00033 { "TMLastStationOptimizedBarrelLowPtLoose", TMLastStationOptimizedBarrelLowPtLoose },
00034 { "TMLastStationOptimizedBarrelLowPtTight", TMLastStationOptimizedBarrelLowPtTight },
00035 { 0, (SelectionType)-1 }
00036 };
00037
00038 SelectionType value = (SelectionType)-1;
00039 bool found = false;
00040 for(int i = 0; selectionTypeStringToEnumMap[i].label && (! found); ++i)
00041 if (! strcmp(label.c_str(), selectionTypeStringToEnumMap[i].label)) {
00042 found = true;
00043 value = selectionTypeStringToEnumMap[i].value;
00044 }
00045
00046
00047 if (! found) throw cms::Exception("MuonSelectorError") << label << " is not a recognized SelectionType";
00048 return value;
00049 }
00050 }
00051
00052 unsigned int muon::RequiredStationMask( const reco::Muon& muon,
00053 double maxChamberDist,
00054 double maxChamberDistPull,
00055 reco::Muon::ArbitrationType arbitrationType )
00056 {
00057 unsigned int theMask = 0;
00058
00059 for(int stationIdx = 1; stationIdx < 5; ++stationIdx)
00060 for(int detectorIdx = 1; detectorIdx < 3; ++detectorIdx)
00061 if(muon.trackDist(stationIdx,detectorIdx,arbitrationType) < maxChamberDist &&
00062 muon.trackDist(stationIdx,detectorIdx,arbitrationType)/muon.trackDistErr(stationIdx,detectorIdx,arbitrationType) < maxChamberDistPull)
00063 theMask += 1<<((stationIdx-1)+4*(detectorIdx-1));
00064
00065 return theMask;
00066 }
00067
00068
00069 float muon::caloCompatibility(const reco::Muon& muon) {
00070 return muon.caloCompatibility();
00071 }
00072
00073
00074 float muon::segmentCompatibility(const reco::Muon& muon,reco::Muon::ArbitrationType arbitrationType) {
00075 bool use_weight_regain_at_chamber_boundary = true;
00076 bool use_match_dist_penalty = true;
00077
00078 int nr_of_stations_crossed = 0;
00079 int nr_of_stations_with_segment = 0;
00080 std::vector<int> stations_w_track(8);
00081 std::vector<int> station_has_segmentmatch(8);
00082 std::vector<int> station_was_crossed(8);
00083 std::vector<float> stations_w_track_at_boundary(8);
00084 std::vector<float> station_weight(8);
00085 int position_in_stations = 0;
00086 float full_weight = 0.;
00087
00088 for(int i = 1; i<=8; ++i) {
00089
00090
00091
00092 if(i<=4) {
00093 if( muon.trackDist(i,1,arbitrationType) < 999999 ) {
00094 ++nr_of_stations_crossed;
00095 station_was_crossed[i-1] = 1;
00096 if(muon.trackDist(i,1,arbitrationType) > -10. ) stations_w_track_at_boundary[i-1] = muon.trackDist(i,1,arbitrationType);
00097 else stations_w_track_at_boundary[i-1] = 0.;
00098 }
00099 if( muon.segmentX(i,1,arbitrationType) < 999999 ) {
00100 ++nr_of_stations_with_segment;
00101 station_has_segmentmatch[i-1] = 1;
00102 }
00103 }
00104 else {
00105 if( muon.trackDist(i-4,2,arbitrationType) < 999999 ) {
00106 ++nr_of_stations_crossed;
00107 station_was_crossed[i-1] = 1;
00108 if(muon.trackDist(i-4,2,arbitrationType) > -10. ) stations_w_track_at_boundary[i-1] = muon.trackDist(i-4,2,arbitrationType);
00109 else stations_w_track_at_boundary[i-1] = 0.;
00110 }
00111 if( muon.segmentX(i-4,2,arbitrationType) < 999999 ) {
00112 ++nr_of_stations_with_segment;
00113 station_has_segmentmatch[i-1] = 1;
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 const float attenuate_weight_regain = 0.5;
00133
00134 for(int i = 1; i<=8; ++i) {
00135
00136
00137
00138
00139
00140 if( station_was_crossed[i-1] > 0 ) {
00141
00142
00143
00144
00145
00146 ++position_in_stations;
00147
00148 switch ( nr_of_stations_crossed ) {
00149 case 1 :
00150 station_weight[i-1] = 1.;
00151 break;
00152 case 2 :
00153 if ( position_in_stations == 1 ) station_weight[i-1] = 0.33;
00154 else station_weight[i-1] = 0.67;
00155 break;
00156 case 3 :
00157 if ( position_in_stations == 1 ) station_weight[i-1] = 0.23;
00158 else if( position_in_stations == 2 ) station_weight[i-1] = 0.33;
00159 else station_weight[i-1] = 0.44;
00160 break;
00161 case 4 :
00162 if ( position_in_stations == 1 ) station_weight[i-1] = 0.10;
00163 else if( position_in_stations == 2 ) station_weight[i-1] = 0.20;
00164 else if( position_in_stations == 3 ) station_weight[i-1] = 0.30;
00165 else station_weight[i-1] = 0.40;
00166 break;
00167
00168 default :
00169
00170
00171
00172 station_weight[i-1] = 1./nr_of_stations_crossed;
00173 }
00174
00175 if( use_weight_regain_at_chamber_boundary ) {
00176 if(station_has_segmentmatch[i-1] <= 0 && stations_w_track_at_boundary[i-1] != 0. ) {
00177
00178
00179
00180 station_weight[i-1] = station_weight[i-1]*attenuate_weight_regain*0.5*(TMath::Erf(stations_w_track_at_boundary[i-1]/6.)+1.);
00181 }
00182 else if(station_has_segmentmatch[i-1] <= 0 && stations_w_track_at_boundary[i-1] == 0.) {
00183
00184 station_weight[i-1] = 0.;
00185 }
00186 }
00187 else {
00188 if(station_has_segmentmatch[i-1] <= 0) station_weight[i-1] = 0.;
00189 }
00190
00191 if( station_has_segmentmatch[i-1] > 0 && 42 == 42 ) {
00192 if(i<=4) {
00193 if( muon.dY(i,1,arbitrationType) < 999999 && muon.dX(i,1,arbitrationType) < 999999) {
00194 if(
00195 TMath::Sqrt(TMath::Power(muon.pullX(i,1,arbitrationType),2.)+TMath::Power(muon.pullY(i,1,arbitrationType),2.))> 1. ) {
00196
00197 if(use_match_dist_penalty) {
00198
00199 if(TMath::Sqrt(TMath::Power(muon.dX(i,1,arbitrationType),2.)+TMath::Power(muon.dY(i,1,arbitrationType),2.)) < 3. && TMath::Sqrt(TMath::Power(muon.pullX(i,1,arbitrationType),2.)+TMath::Power(muon.pullY(i,1,arbitrationType),2.)) > 3. ) {
00200 station_weight[i-1] *= 1./TMath::Power(
00201 TMath::Max((double)TMath::Sqrt(TMath::Power(muon.dX(i,1,arbitrationType),2.)+TMath::Power(muon.dY(i,1,arbitrationType),2.)),(double)1.),.25);
00202 }
00203 else {
00204 station_weight[i-1] *= 1./TMath::Power(
00205 TMath::Sqrt(TMath::Power(muon.pullX(i,1,arbitrationType),2.)+TMath::Power(muon.pullY(i,1,arbitrationType),2.)),.25);
00206 }
00207 }
00208 }
00209 }
00210 else if (muon.dY(i,1,arbitrationType) >= 999999) {
00211 if( muon.pullX(i,1,arbitrationType) > 1. ) {
00212
00213 if(use_match_dist_penalty) {
00214
00215 if( muon.dX(i,1,arbitrationType) < 3. && muon.pullX(i,1,arbitrationType) > 3. ) {
00216 station_weight[i-1] *= 1./TMath::Power(TMath::Max((double)muon.dX(i,1,arbitrationType),(double)1.),.25);
00217 }
00218 else {
00219 station_weight[i-1] *= 1./TMath::Power(muon.pullX(i,1,arbitrationType),.25);
00220 }
00221 }
00222 }
00223 }
00224 else {
00225 if( muon.pullY(i,1,arbitrationType) > 1. ) {
00226
00227 if(use_match_dist_penalty) {
00228
00229 if( muon.dY(i,1,arbitrationType) < 3. && muon.pullY(i,1,arbitrationType) > 3. ) {
00230 station_weight[i-1] *= 1./TMath::Power(TMath::Max((double)muon.dY(i,1,arbitrationType),(double)1.),.25);
00231 }
00232 else {
00233 station_weight[i-1] *= 1./TMath::Power(muon.pullY(i,1,arbitrationType),.25);
00234 }
00235 }
00236 }
00237 }
00238 }
00239 else {
00240 if(
00241 TMath::Sqrt(TMath::Power(muon.pullX(i-4,2,arbitrationType),2.)+TMath::Power(muon.pullY(i-4,2,arbitrationType),2.)) > 1. ) {
00242
00243 if(use_match_dist_penalty) {
00244
00245 if(TMath::Sqrt(TMath::Power(muon.dX(i-4,2,arbitrationType),2.)+TMath::Power(muon.dY(i-4,2,arbitrationType),2.)) < 3. && TMath::Sqrt(TMath::Power(muon.pullX(i-4,2,arbitrationType),2.)+TMath::Power(muon.pullY(i-4,2,arbitrationType),2.)) > 3. ) {
00246 station_weight[i-1] *= 1./TMath::Power(
00247 TMath::Max((double)TMath::Sqrt(TMath::Power(muon.dX(i-4,2,arbitrationType),2.)+TMath::Power(muon.dY(i-4,2,arbitrationType),2.)),(double)1.),.25);
00248 }
00249 else {
00250 station_weight[i-1] *= 1./TMath::Power(
00251 TMath::Sqrt(TMath::Power(muon.pullX(i-4,2,arbitrationType),2.)+TMath::Power(muon.pullY(i-4,2,arbitrationType),2.)),.25);
00252 }
00253 }
00254 }
00255 }
00256 }
00257
00258
00259
00260
00261
00262 }
00263 else {
00264 station_weight[i-1] = 0.;
00265 }
00266
00267
00268 full_weight += station_weight[i-1];
00269 }
00270
00271
00272
00273
00274 if( nr_of_stations_crossed == 0 ) {
00275
00276 full_weight = 0.5;
00277 }
00278
00279
00280
00281
00282
00283 return full_weight;
00284
00285 }
00286
00287 bool muon::isGoodMuon( const reco::Muon& muon,
00288 AlgorithmType type,
00289 double minCompatibility,
00290 reco::Muon::ArbitrationType arbitrationType ) {
00291 if (!muon.isMatchesValid()) return false;
00292 bool goodMuon = false;
00293
00294 switch( type ) {
00295 case TM2DCompatibility:
00296
00297 if( ( (0.8*caloCompatibility( muon ))+(1.2*segmentCompatibility( muon, arbitrationType )) ) > minCompatibility ) goodMuon = true;
00298 else goodMuon = false;
00299 return goodMuon;
00300 break;
00301 default :
00302
00303 goodMuon = false;
00304 return goodMuon;
00305 break;
00306 }
00307 }
00308
00309 bool muon::isGoodMuon( const reco::Muon& muon,
00310 AlgorithmType type,
00311 int minNumberOfMatches,
00312 double maxAbsDx,
00313 double maxAbsPullX,
00314 double maxAbsDy,
00315 double maxAbsPullY,
00316 double maxChamberDist,
00317 double maxChamberDistPull,
00318 reco::Muon::ArbitrationType arbitrationType,
00319 bool syncMinNMatchesNRequiredStationsInBarrelOnly,
00320 bool applyAlsoAngularCuts)
00321 {
00322 if (!muon.isMatchesValid()) return false;
00323 bool goodMuon = false;
00324
00325 if (type == TMLastStation) {
00326
00327
00328 if(minNumberOfMatches == 0) return true;
00329
00330 unsigned int theStationMask = muon.stationMask(arbitrationType);
00331 unsigned int theRequiredStationMask = RequiredStationMask(muon, maxChamberDist, maxChamberDistPull, arbitrationType);
00332
00333
00334 int numSegs = 0;
00335 int numRequiredStations = 0;
00336 for(int it = 0; it < 8; ++it) {
00337 if(theStationMask & 1<<it) ++numSegs;
00338 if(theRequiredStationMask & 1<<it) ++numRequiredStations;
00339 }
00340
00341
00342
00343 if (syncMinNMatchesNRequiredStationsInBarrelOnly) {
00344
00345 if (fabs(muon.eta()) < 1.2) {
00346 if(minNumberOfMatches > numRequiredStations)
00347 minNumberOfMatches = numRequiredStations;
00348 if(minNumberOfMatches < 1)
00349 minNumberOfMatches = 1;
00350 }
00351 } else {
00352 if(minNumberOfMatches > numRequiredStations)
00353 minNumberOfMatches = numRequiredStations;
00354 if(minNumberOfMatches < 1)
00355 minNumberOfMatches = 1;
00356 }
00357
00358 if(numSegs >= minNumberOfMatches) goodMuon = 1;
00359
00360
00361
00362
00363
00364 int lastSegBit = 0;
00365 if(theRequiredStationMask) {
00366 for(int stationIdx = 7; stationIdx >= 0; --stationIdx)
00367 if(theRequiredStationMask & 1<<stationIdx){
00368 if(theStationMask & 1<<stationIdx) {
00369 lastSegBit = stationIdx;
00370 goodMuon &= 1;
00371 break;
00372 } else {
00373 goodMuon = false;
00374 break;
00375 }
00376 }
00377 } else {
00378 for(int stationIdx = 7; stationIdx >= 0; --stationIdx)
00379 if(theStationMask & 1<<stationIdx) {
00380 lastSegBit = stationIdx;
00381 break;
00382 }
00383 }
00384
00385 if(!goodMuon) return false;
00386
00387
00388 int station = 0, detector = 0;
00389 station = lastSegBit < 4 ? lastSegBit+1 : lastSegBit-3;
00390 detector = lastSegBit < 4 ? 1 : 2;
00391
00392
00393 if(fabs(muon.pullX(station,detector,arbitrationType,1)) > maxAbsPullX &&
00394 fabs(muon.dX(station,detector,arbitrationType)) > maxAbsDx)
00395 return false;
00396
00397 if(applyAlsoAngularCuts && fabs(muon.pullDxDz(station,detector,arbitrationType,1)) > maxAbsPullX)
00398 return false;
00399
00400
00401 if (maxAbsDy < 999999) {
00402
00403
00404 if (detector == 2) {
00405 if(fabs(muon.pullY(station,2,arbitrationType,1)) > maxAbsPullY &&
00406 fabs(muon.dY(station,2,arbitrationType)) > maxAbsDy)
00407 return false;
00408
00409 if(applyAlsoAngularCuts && fabs(muon.pullDyDz(station,2,arbitrationType,1)) > maxAbsPullY)
00410 return false;
00411 } else {
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 for (int stationIdx = station; stationIdx > 0; --stationIdx) {
00428 if(! (theStationMask & 1<<(stationIdx-1)))
00429 continue;
00430
00431 if(muon.dY(stationIdx,1,arbitrationType) > 999998)
00432 continue;
00433
00434 if(fabs(muon.pullY(stationIdx,1,arbitrationType,1)) > maxAbsPullY &&
00435 fabs(muon.dY(stationIdx,1,arbitrationType)) > maxAbsDy) {
00436 return false;
00437 }
00438
00439 if(applyAlsoAngularCuts && fabs(muon.pullDyDz(stationIdx,1,arbitrationType,1)) > maxAbsPullY)
00440 return false;
00441
00442
00443 return true;
00444 }
00445 }
00446 }
00447
00448 return goodMuon;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 if (type == TMOneStation) {
00462 unsigned int theStationMask = muon.stationMask(arbitrationType);
00463
00464
00465 if (! theStationMask) return false;
00466
00467 int station = 0, detector = 0;
00468
00469
00470
00471
00472 bool existsGoodDTSegX = false;
00473 bool existsDTSegY = false;
00474
00475
00476
00477 for(int stationIdx = 0; stationIdx <= 7; ++stationIdx)
00478 if(theStationMask & 1<<stationIdx) {
00479 station = stationIdx < 4 ? stationIdx+1 : stationIdx-3;
00480 detector = stationIdx < 4 ? 1 : 2;
00481
00482 if((fabs(muon.pullX(station,detector,arbitrationType,1)) > maxAbsPullX &&
00483 fabs(muon.dX(station,detector,arbitrationType)) > maxAbsDx) ||
00484 (applyAlsoAngularCuts && fabs(muon.pullDxDz(station,detector,arbitrationType,1)) > maxAbsPullX))
00485 continue;
00486 else if (detector == 1)
00487 existsGoodDTSegX = true;
00488
00489
00490 if (maxAbsDy < 999999) {
00491 if (detector == 2) {
00492 if((fabs(muon.pullY(station,2,arbitrationType,1)) > maxAbsPullY &&
00493 fabs(muon.dY(station,2,arbitrationType)) > maxAbsDy) ||
00494 (applyAlsoAngularCuts && fabs(muon.pullDyDz(station,2,arbitrationType,1)) > maxAbsPullY))
00495 continue;
00496 } else {
00497
00498 if(muon.dY(station,1,arbitrationType) > 999998)
00499 continue;
00500 else
00501 existsDTSegY = true;
00502
00503 if((fabs(muon.pullY(station,1,arbitrationType,1)) > maxAbsPullY &&
00504 fabs(muon.dY(station,1,arbitrationType)) > maxAbsDy) ||
00505 (applyAlsoAngularCuts && fabs(muon.pullDyDz(station,1,arbitrationType,1)) > maxAbsPullY)) {
00506 continue;
00507 }
00508 }
00509 }
00510
00511
00512 return true;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522 if (maxAbsDy < 999999) {
00523 if (existsDTSegY)
00524 return false;
00525 else if (existsGoodDTSegX)
00526 return true;
00527 } else
00528 return false;
00529 }
00530
00531 return goodMuon;
00532 }
00533
00534 bool muon::isGoodMuon( const reco::Muon& muon, SelectionType type,
00535 reco::Muon::ArbitrationType arbitrationType)
00536 {
00537 switch (type)
00538 {
00539 case muon::All:
00540 return true;
00541 break;
00542 case muon::AllGlobalMuons:
00543 return muon.isGlobalMuon();
00544 break;
00545 case muon::AllTrackerMuons:
00546 return muon.isTrackerMuon();
00547 break;
00548 case muon::AllStandAloneMuons:
00549 return muon.isStandAloneMuon();
00550 break;
00551 case muon::TrackerMuonArbitrated:
00552 return muon.isTrackerMuon() && muon.numberOfMatches(arbitrationType)>0;
00553 break;
00554 case muon::AllArbitrated:
00555 return ! muon.isTrackerMuon() || muon.numberOfMatches(arbitrationType)>0;
00556 break;
00557 case muon::GlobalMuonPromptTight:
00558 return muon.isGlobalMuon() && muon.globalTrack()->normalizedChi2()<10. && muon.globalTrack()->hitPattern().numberOfValidMuonHits() >0;
00559 break;
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 case muon::TMLastStationLoose:
00571 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,1E9,1E9,-3,-3,arbitrationType,true,false);
00572 break;
00573 case muon::TMLastStationTight:
00574 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,3,3,-3,-3,arbitrationType,true,false);
00575 break;
00576 case muon::TMOneStationLoose:
00577 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,1E9,1E9,1E9,1E9,arbitrationType,false,false);
00578 break;
00579 case muon::TMOneStationTight:
00580 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,3,3,1E9,1E9,arbitrationType,false,false);
00581 break;
00582 case muon::TMLastStationOptimizedLowPtLoose:
00583 if (muon.pt() < 8. && fabs(muon.eta()) < 1.2)
00584 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,1E9,1E9,1E9,1E9,arbitrationType,false,false);
00585 else
00586 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,1E9,1E9,-3,-3,arbitrationType,false,false);
00587 break;
00588 case muon::TMLastStationOptimizedLowPtTight:
00589 if (muon.pt() < 8. && fabs(muon.eta()) < 1.2)
00590 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,3,3,1E9,1E9,arbitrationType,false,false);
00591 else
00592 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,3,3,-3,-3,arbitrationType,false,false);
00593 break;
00594
00595 case muon::TM2DCompatibilityLoose:
00596 return muon.isTrackerMuon() && isGoodMuon(muon,TM2DCompatibility,0.7,arbitrationType);
00597 break;
00598
00599 case muon::TM2DCompatibilityTight:
00600 return muon.isTrackerMuon() && isGoodMuon(muon,TM2DCompatibility,1.0,arbitrationType);
00601 break;
00602 case muon::GMTkChiCompatibility:
00603 return muon.isGlobalMuon() && muon.isQualityValid() && fabs(muon.combinedQuality().trkRelChi2 - muon.innerTrack()->normalizedChi2()) < 2.0;
00604 break;
00605 case muon::GMStaChiCompatibility:
00606 return muon.isGlobalMuon() && muon.isQualityValid() && fabs(muon.combinedQuality().staRelChi2 - muon.outerTrack()->normalizedChi2()) < 2.0;
00607 break;
00608 case muon::GMTkKinkTight:
00609 return muon.isGlobalMuon() && muon.isQualityValid() && muon.combinedQuality().trkKink < 100.0;
00610 break;
00611 case muon::TMLastStationAngLoose:
00612 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,1E9,1E9,-3,-3,arbitrationType,false,true);
00613 break;
00614 case muon::TMLastStationAngTight:
00615 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,3,3,-3,-3,arbitrationType,false,true);
00616 break;
00617 case muon::TMOneStationAngLoose:
00618 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,1E9,1E9,1E9,1E9,arbitrationType,false,true);
00619 break;
00620 case muon::TMOneStationAngTight:
00621 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,3,3,1E9,1E9,arbitrationType,false,true);
00622 break;
00623 case muon::TMLastStationOptimizedBarrelLowPtLoose:
00624 if (muon.pt() < 8. && fabs(muon.eta()) < 1.2)
00625 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,1E9,1E9,1E9,1E9,arbitrationType,false,false);
00626 else
00627 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,1E9,1E9,-3,-3,arbitrationType,true,false);
00628 break;
00629 case muon::TMLastStationOptimizedBarrelLowPtTight:
00630 if (muon.pt() < 8. && fabs(muon.eta()) < 1.2)
00631 return muon.isTrackerMuon() && isGoodMuon(muon,TMOneStation,1,3,3,3,3,1E9,1E9,arbitrationType,false,false);
00632 else
00633 return muon.isTrackerMuon() && isGoodMuon(muon,TMLastStation,2,3,3,3,3,-3,-3,arbitrationType,true,false);
00634 break;
00635 default:
00636 return false;
00637 }
00638 }
00639
00640 bool muon::overlap( const reco::Muon& muon1, const reco::Muon& muon2,
00641 double pullX, double pullY, bool checkAdjacentChambers)
00642 {
00643 unsigned int nMatches1 = muon1.numberOfMatches(reco::Muon::SegmentAndTrackArbitration);
00644 unsigned int nMatches2 = muon2.numberOfMatches(reco::Muon::SegmentAndTrackArbitration);
00645 unsigned int betterMuon = ( muon1.pt() > muon2.pt() ? 1 : 2 );
00646 for ( std::vector<reco::MuonChamberMatch>::const_iterator chamber1 = muon1.matches().begin();
00647 chamber1 != muon1.matches().end(); ++chamber1 )
00648 for ( std::vector<reco::MuonChamberMatch>::const_iterator chamber2 = muon2.matches().begin();
00649 chamber2 != muon2.matches().end(); ++chamber2 )
00650 {
00651
00652
00653
00654
00655
00656 if ( chamber1->id == chamber2->id ){
00657
00658 if ( fabs(chamber1->x-chamber2->x) <
00659 pullX * sqrt(chamber1->xErr*chamber1->xErr+chamber2->xErr*chamber2->xErr) )
00660 {
00661 if ( betterMuon == 1 )
00662 nMatches2--;
00663 else
00664 nMatches1--;
00665 if ( nMatches1==0 || nMatches2==0 ) return true;
00666 continue;
00667 }
00668 if ( fabs(chamber1->y-chamber2->y) <
00669 pullY * sqrt(chamber1->yErr*chamber1->yErr+chamber2->yErr*chamber2->yErr) )
00670 {
00671 if ( betterMuon == 1 )
00672 nMatches2--;
00673 else
00674 nMatches1--;
00675 if ( nMatches1==0 || nMatches2==0 ) return true;
00676 }
00677 } else {
00678 if ( ! checkAdjacentChambers ) continue;
00679
00680 if ( chamber1->id.subdetId() != MuonSubdetId::CSC ||
00681 chamber2->id.subdetId() != MuonSubdetId::CSC ) continue;
00682 CSCDetId id1(chamber1->id);
00683 CSCDetId id2(chamber2->id);
00684 if ( id1.endcap() != id2.endcap() ) continue;
00685 if ( id1.station() != id2.station() ) continue;
00686 if ( id1.ring() != id2.ring() ) continue;
00687 if ( abs(id1.chamber() - id2.chamber())>1 ) continue;
00688
00689
00690
00691
00692
00693
00694 if ( fabs(chamber1->edgeX) > chamber1->xErr*pullX ) continue;
00695 if ( fabs(chamber2->edgeX) > chamber2->xErr*pullX ) continue;
00696 if ( chamber1->x * chamber2->x < 0 ) {
00697 if ( betterMuon == 1 )
00698 nMatches2--;
00699 else
00700 nMatches1--;
00701 if ( nMatches1==0 || nMatches2==0 ) return true;
00702 }
00703 }
00704 }
00705 return false;
00706 }
00707
00708
00709 bool muon::isTightMuon(const reco::Muon& muon, const reco::Vertex& vtx){
00710
00711 if(!muon.isPFMuon() || !muon.isGlobalMuon() ) return false;
00712
00713 bool muID = isGoodMuon(muon,GlobalMuonPromptTight) && (muon.numberOfMatchedStations() > 1);
00714
00715
00716 bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
00717 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
00718
00719
00720 bool ip = fabs(muon.muonBestTrack()->dxy(vtx.position())) < 0.2 && fabs(muon.muonBestTrack()->dz(vtx.position())) < 0.5;
00721
00722 return muID && hits && ip;
00723 }
00724
00725 bool muon::isLooseMuon(const reco::Muon& muon){
00726 return muon.isPFMuon() && ( muon.isGlobalMuon() || muon.isTrackerMuon());
00727 }
00728
00729 bool muon::isSoftMuon(const reco::Muon& muon, const reco::Vertex& vtx){
00730
00731 bool muID = muon::isGoodMuon(muon, TMOneStationTight);
00732 if(!muID) return false;
00733
00734 bool layers = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 && muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 1;
00735
00736 bool chi2 = muon.innerTrack()->normalizedChi2() < 1.8;
00737
00738 bool ip = fabs(muon.innerTrack()->dxy(vtx.position())) < 3. && fabs(muon.innerTrack()->dz(vtx.position())) < 30.;
00739
00740 return muID && layers && ip && chi2;
00741 }
00742
00743 bool muon::isHighPtMuon(const reco::Muon& muon, const reco::Vertex& vtx, reco::TunePType tunePType){
00744
00745 bool muID = muon.isGlobalMuon() && muon.globalTrack()->hitPattern().numberOfValidMuonHits() >0 && (muon.numberOfMatchedStations() > 1);
00746 if(!muID) return false;
00747
00748 if(tunePType == reco::improvedTuneP){
00749
00750 reco::TrackRef cktTrack = (muon::tevOptimized(muon, 200, 17., 40., 0.25)).first;
00751
00752
00753 bool momQuality = cktTrack->ptError()/cktTrack->pt() < 0.3;
00754
00755
00756 bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 && muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
00757
00758
00759
00760 bool ip = fabs(cktTrack->dxy(vtx.position())) < 0.2 && fabs(cktTrack->dz(vtx.position())) < 0.5;
00761
00762
00763
00764 return muID && hits && momQuality && ip;}
00765
00766 else if(tunePType == reco::defaultTuneP){
00767
00768 reco::TrackRef cktTrack = (muon::tevOptimized(muon, 200, 4., 6., -1)).first;
00769
00770 bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 8 && muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
00771
00772 bool ip = fabs(cktTrack->dxy(vtx.position())) < 0.2 && fabs(cktTrack->dz(vtx.position())) < 0.5;
00773
00774 return muID && hits && ip;}
00775
00776 else return false;
00777 }
00778
00779
00780 int muon::sharedSegments( const reco::Muon& mu, const reco::Muon& mu2, unsigned int segmentArbitrationMask ) {
00781 int ret = 0;
00782
00783
00784 for(std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch = mu.matches().begin();
00785 chamberMatch != mu.matches().end(); ++chamberMatch) {
00786 if (chamberMatch->segmentMatches.empty()) continue;
00787 for(std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch2 = mu2.matches().begin();
00788 chamberMatch2 != mu2.matches().end(); ++chamberMatch2) {
00789 if (chamberMatch2->segmentMatches.empty()) continue;
00790 if (chamberMatch2->id() != chamberMatch->id()) continue;
00791 for(std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch = chamberMatch->segmentMatches.begin();
00792 segmentMatch != chamberMatch->segmentMatches.end(); ++segmentMatch) {
00793 if (!segmentMatch->isMask(segmentArbitrationMask)) continue;
00794 for(std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch2 = chamberMatch2->segmentMatches.begin();
00795 segmentMatch2 != chamberMatch2->segmentMatches.end(); ++segmentMatch2) {
00796 if (!segmentMatch2->isMask(segmentArbitrationMask)) continue;
00797 if ((segmentMatch->cscSegmentRef.isNonnull() && segmentMatch->cscSegmentRef == segmentMatch2->cscSegmentRef) ||
00798 (segmentMatch-> dtSegmentRef.isNonnull() && segmentMatch-> dtSegmentRef == segmentMatch2-> dtSegmentRef) ) {
00799 ++ret;
00800 }
00801 }
00802 }
00803 }
00804 }
00805
00806 return ret;
00807 }