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