35 throw cms::Exception(
"MuonSelectorError") <<
label <<
" is not a recognized reco::Muon::Selector";
41 double maxChamberDist,
42 double maxChamberDistPull,
44 unsigned int theMask = 0;
46 for (
int stationIdx = 1; stationIdx < 5; ++stationIdx) {
47 for (
int detectorIdx = 1; detectorIdx < 3; ++detectorIdx) {
49 if (dist < maxChamberDist &&
51 theMask += 1 << ((stationIdx - 1) + 4 * (detectorIdx - 1));
62 bool use_weight_regain_at_chamber_boundary =
true;
63 bool use_match_dist_penalty =
true;
65 int nr_of_stations_crossed = 0;
66 std::vector<int> stations_w_track(8);
67 std::vector<int> station_has_segmentmatch(8);
68 std::vector<int> station_was_crossed(8);
69 std::vector<float> stations_w_track_at_boundary(8);
70 std::vector<float> station_weight(8);
71 int position_in_stations = 0;
72 float full_weight = 0.;
74 for (
int i = 1;
i <= 8; ++
i) {
80 if (thisTrackDist < 999999) {
81 ++nr_of_stations_crossed;
82 station_was_crossed[
i - 1] = 1;
83 if (thisTrackDist > -10.)
84 stations_w_track_at_boundary[
i - 1] = thisTrackDist;
86 stations_w_track_at_boundary[
i - 1] = 0.;
90 station_has_segmentmatch[
i - 1] = 1;
94 if (thisTrackDist < 999999) {
95 ++nr_of_stations_crossed;
96 station_was_crossed[
i - 1] = 1;
97 if (thisTrackDist > -10.)
98 stations_w_track_at_boundary[
i - 1] = thisTrackDist;
100 stations_w_track_at_boundary[
i - 1] = 0.;
104 station_has_segmentmatch[
i - 1] = 1;
123 const float attenuate_weight_regain = 0.5;
125 for (
int i = 1;
i <= 8; ++
i) {
131 if (station_was_crossed[
i - 1] > 0) {
137 ++position_in_stations;
139 switch (nr_of_stations_crossed) {
141 station_weight[
i - 1] = 1.f;
144 if (position_in_stations == 1)
145 station_weight[
i - 1] = 0.33f;
147 station_weight[
i - 1] = 0.67f;
150 if (position_in_stations == 1)
151 station_weight[
i - 1] = 0.23f;
152 else if (position_in_stations == 2)
153 station_weight[
i - 1] = 0.33f;
155 station_weight[
i - 1] = 0.44f;
158 if (position_in_stations == 1)
159 station_weight[
i - 1] = 0.10f;
160 else if (position_in_stations == 2)
161 station_weight[
i - 1] = 0.20f;
162 else if (position_in_stations == 3)
163 station_weight[
i - 1] = 0.30f;
165 station_weight[
i - 1] = 0.40f;
172 station_weight[
i - 1] = 1.f / nr_of_stations_crossed;
175 if (use_weight_regain_at_chamber_boundary) {
176 if (station_has_segmentmatch[
i - 1] <= 0 && stations_w_track_at_boundary[
i - 1] != 0.) {
181 station_weight[
i - 1] = station_weight[
i - 1] * attenuate_weight_regain * 0.5f *
182 (std::erf(stations_w_track_at_boundary[
i - 1] / 6.
f) + 1.f);
183 }
else if (station_has_segmentmatch[
i - 1] <= 0 &&
184 stations_w_track_at_boundary[
i - 1] == 0.
f) {
186 station_weight[
i - 1] = 0.f;
189 if (station_has_segmentmatch[
i - 1] <= 0)
190 station_weight[
i - 1] = 0.f;
194 if (station_has_segmentmatch[
i - 1] > 0) {
198 const float pullTot2 =
200 if (pullTot2 > 1.
f) {
204 if (use_match_dist_penalty) {
206 if (dxy2 < 9.f && pullTot2 > 9.
f) {
208 station_weight[
i - 1] *= 1.f /
std::pow(dxy2, .125);
210 station_weight[
i - 1] *= 1.f /
std::pow(pullTot2, .125);
218 if (use_match_dist_penalty) {
232 if (use_match_dist_penalty) {
244 const float pullTot2 =
246 if (pullTot2 > 1.
f) {
248 if (use_match_dist_penalty) {
252 if (dxy2 < 9.f && pullTot2 > 9.
f) {
254 station_weight[
i - 1] *= 1.f /
std::pow(dxy2, .125);
256 station_weight[
i - 1] *= 1.f /
std::pow(pullTot2, .125);
268 station_weight[
i - 1] = 0.f;
272 full_weight += station_weight[
i - 1];
278 if (nr_of_stations_crossed == 0) {
292 double minCompatibility,
294 if (!
muon.isMatchesValid())
296 bool goodMuon =
false;
322 double maxChamberDist,
323 double maxChamberDistPull,
325 bool syncMinNMatchesNRequiredStationsInBarrelOnly,
326 bool applyAlsoAngularCuts) {
327 if (!
muon.isMatchesValid())
329 bool goodMuon =
false;
338 unsigned int theRequiredStationMask =
343 int numRequiredStations = 0;
344 for (
int it = 0; it < 8; ++it) {
345 if (theStationMask & 1 << it)
347 if (theRequiredStationMask & 1 << it)
348 ++numRequiredStations;
353 if (syncMinNMatchesNRequiredStationsInBarrelOnly) {
376 if (theRequiredStationMask) {
377 for (
int stationIdx = 7; stationIdx >= 0; --stationIdx)
378 if (theRequiredStationMask & 1 << stationIdx) {
379 if (theStationMask & 1 << stationIdx) {
380 lastSegBit = stationIdx;
389 for (
int stationIdx = 7; stationIdx >= 0; --stationIdx)
390 if (theStationMask & 1 << stationIdx) {
391 lastSegBit = stationIdx;
401 station = lastSegBit < 4 ? lastSegBit + 1 : lastSegBit - 3;
439 for (
int stationIdx =
station; stationIdx > 0; --stationIdx) {
440 if (!(theStationMask & 1 << (stationIdx - 1)))
485 bool existsGoodDTSegX =
false;
486 bool existsDTSegY =
false;
490 for (
int stationIdx = 0; stationIdx <= 7; ++stationIdx)
491 if (theStationMask & 1 << stationIdx) {
492 station = stationIdx < 4 ? stationIdx + 1 : stationIdx - 3;
500 existsGoodDTSegX =
true;
537 else if (existsGoodDTSegX)
548 for (
const auto& chamberMatch :
muon.matches()) {
552 const float trkX = chamberMatch.x;
553 const float errX = chamberMatch.xErr;
555 for (
const auto& rpcMatch : chamberMatch.rpcMatches) {
556 const float rpcX = rpcMatch.x;
557 const float dX =
std::abs(rpcX - trkX);
576 for (
const auto& chamberMatch :
muon.matches()) {
580 const float trkX = chamberMatch.x;
581 const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
582 const float trkY = chamberMatch.y;
583 const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
585 for (
const auto& segment : chamberMatch.me0Matches) {
586 const float me0X = segment.x;
587 const float me0ErrX2 = segment.xErr * segment.xErr;
588 const float me0Y = segment.y;
589 const float me0ErrY2 = segment.yErr * segment.yErr;
591 const float dX =
std::abs(me0X - trkX);
592 const float dY =
std::abs(me0Y - trkY);
593 const float invPullX2 = errX2 + me0ErrX2;
594 const float invPullY2 = errY2 + me0ErrY2;
612 for (
const auto& chamberMatch :
muon.matches()) {
616 const float trkX = chamberMatch.x;
617 const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
618 const float trkY = chamberMatch.y;
619 const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
621 for (
const auto& segment : chamberMatch.gemMatches) {
622 const float gemX = segment.x;
623 const float gemErrX2 = segment.xErr * segment.xErr;
624 const float gemY = segment.y;
625 const float gemErrY2 = segment.yErr * segment.yErr;
627 const float dX =
std::abs(gemX - trkX);
628 const float dY =
std::abs(gemY - trkY);
629 const float invPullX2 = errX2 + gemErrX2;
630 const float invPullY2 = errY2 + gemErrY2;
652 return muon.isGlobalMuon();
655 return muon.isTrackerMuon();
658 return muon.isStandAloneMuon();
667 return muon.isGlobalMuon() &&
muon.globalTrack()->normalizedChi2() < 10. &&
668 muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0;
681 return muon.isTrackerMuon() &&
682 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
true,
false);
685 return muon.isTrackerMuon() &&
686 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
true,
false);
689 return muon.isTrackerMuon() &&
690 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
693 return muon.isTrackerMuon() &&
694 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
698 return muon.isTrackerMuon() &&
699 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
701 return muon.isTrackerMuon() &&
702 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
false,
false);
706 return muon.isTrackerMuon() &&
707 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
709 return muon.isTrackerMuon() &&
710 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
false,
false);
721 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
722 std::abs(
muon.combinedQuality().trkRelChi2 -
muon.innerTrack()->normalizedChi2()) < 2.0;
725 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
726 std::abs(
muon.combinedQuality().staRelChi2 -
muon.outerTrack()->normalizedChi2()) < 2.0;
729 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
muon.combinedQuality().trkKink < 100.0;
732 return muon.isTrackerMuon() &&
733 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
false,
true);
736 return muon.isTrackerMuon() &&
737 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
false,
true);
740 return muon.isTrackerMuon() &&
741 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
true);
744 return muon.isTrackerMuon() &&
745 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
true);
749 return muon.isTrackerMuon() &&
750 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
752 return muon.isTrackerMuon() &&
753 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
true,
false);
757 return muon.isTrackerMuon() &&
758 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
760 return muon.isTrackerMuon() &&
761 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
true,
false);
764 return muon.isRPCMuon() &&
isGoodMuon(
muon,
RPCMu, 2, 20, 4, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
767 return muon.isME0Muon();
770 return muon.isME0Muon() &&
771 isGoodMuon(
muon,
ME0Mu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
774 return muon.isGEMMuon();
777 return muon.isGEMMuon() &&
778 isGoodMuon(
muon,
GEMMu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
789 const reco::Muon& muon1,
const reco::Muon& muon2,
double pullX,
double pullY,
bool checkAdjacentChambers) {
792 unsigned int betterMuon = (muon1.
pt() > muon2.
pt() ? 1 : 2);
793 for (std::vector<reco::MuonChamberMatch>::const_iterator chamber1 = muon1.
matches().begin();
794 chamber1 != muon1.
matches().end();
796 for (std::vector<reco::MuonChamberMatch>::const_iterator chamber2 = muon2.
matches().begin();
797 chamber2 != muon2.
matches().end();
803 if (chamber1->id == chamber2->id) {
805 if (
std::abs(chamber1->x - chamber2->x) <
806 pullX *
sqrt(chamber1->xErr * chamber1->xErr + chamber2->xErr * chamber2->xErr)) {
811 if (nMatches1 == 0 || nMatches2 == 0)
815 if (
std::abs(chamber1->y - chamber2->y) <
816 pullY *
sqrt(chamber1->yErr * chamber1->yErr + chamber2->yErr * chamber2->yErr)) {
821 if (nMatches1 == 0 || nMatches2 == 0)
825 if (!checkAdjacentChambers)
832 if (
id1.endcap() !=
id2.endcap())
834 if (
id1.station() !=
id2.station())
836 if (
id1.ring() !=
id2.ring())
846 if (
std::abs(chamber1->edgeX) > chamber1->xErr * pullX)
848 if (
std::abs(chamber2->edgeX) > chamber2->xErr * pullX)
850 if (chamber1->x * chamber2->x < 0) {
855 if (nMatches1 == 0 || nMatches2 == 0)
870 bool layer_requirements =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
871 muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
872 bool match_requirements =
873 (
muon.expectedNnumberOfMatchedStations() < 2)
or (
muon.numberOfMatchedStations() > 1)
or (
muon.pt() < 8);
874 return layer_requirements and match_requirements;
878 if (!
muon.isPFMuon() || !
muon.isGlobalMuon())
883 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
884 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
889 return muID &&
hits && ip;
893 return muon.isPFMuon() && (
muon.isGlobalMuon() ||
muon.isTrackerMuon());
899 if (run2016_hip_mitigation) {
900 if (
muon.innerTrack()->validFraction() < 0.49)
903 if (
muon.innerTrack()->validFraction() < 0.8)
907 bool goodGlb =
muon.isGlobalMuon() &&
muon.globalTrack()->normalizedChi2() < 3. &&
908 muon.combinedQuality().chi2LocalPosition < 12. &&
muon.combinedQuality().trkKink < 20.;
919 bool layers =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
920 muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
927 return layers && ip && (ishighq | run2016_hip_mitigation);
931 if (!
muon.isGlobalMuon())
934 bool muValHits = (
muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 ||
935 muon.tunePMuonBestTrack()->hitPattern().numberOfValidMuonHits() > 0);
937 bool muMatchedSt =
muon.numberOfMatchedStations() > 1;
939 if (
muon.isTrackerMuon() &&
muon.numberOfMatchedStations() == 1) {
940 if (
muon.expectedNnumberOfMatchedStations() < 2 || !(
muon.stationMask() == 1 ||
muon.stationMask() == 16) ||
941 muon.numberOfMatchedRPCLayers() > 2)
946 bool muID = muValHits && muMatchedSt;
948 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
949 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
951 bool momQuality =
muon.tunePMuonBestTrack()->ptError() /
muon.tunePMuonBestTrack()->pt() < 0.3;
956 return muID &&
hits && momQuality && ip;
960 bool muID =
muon.isTrackerMuon() &&
muon.track().isNonnull() && (
muon.numberOfMatchedStations() > 1);
964 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
965 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
967 bool momQuality =
muon.tunePMuonBestTrack()->ptError() < 0.3 *
muon.tunePMuonBestTrack()->pt();
972 return muID &&
hits && momQuality && ip;
979 for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch =
mu.matches().begin();
980 chamberMatch !=
mu.matches().end();
982 if (chamberMatch->segmentMatches.empty())
984 for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch2 = mu2.
matches().begin();
985 chamberMatch2 != mu2.
matches().end();
987 if (chamberMatch2->segmentMatches.empty())
989 if (chamberMatch2->id() != chamberMatch->id())
991 for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch = chamberMatch->segmentMatches.begin();
992 segmentMatch != chamberMatch->segmentMatches.end();
994 if (!segmentMatch->isMask(segmentArbitrationMask))
996 for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch2 = chamberMatch2->segmentMatches.begin();
997 segmentMatch2 != chamberMatch2->segmentMatches.end();
999 if (!segmentMatch2->isMask(segmentArbitrationMask))
1001 if ((segmentMatch->cscSegmentRef.isNonnull() &&
1002 segmentMatch->cscSegmentRef == segmentMatch2->cscSegmentRef) ||
1003 (segmentMatch->dtSegmentRef.isNonnull() && segmentMatch->dtSegmentRef == segmentMatch2->dtSegmentRef)) {
1015 const auto& combinedTime =
muon.time();
1016 const auto& rpcTime =
muon.rpcTime();
1017 bool combinedTimeIsOk = (combinedTime.nDof > 7);
1018 bool rpcTimeIsOk = (rpcTime.nDof > 1 &&
std::abs(rpcTime.timeAtIpInOutErr) < 0.001);
1019 bool outOfTime =
false;
1021 if ((
std::abs(rpcTime.timeAtIpInOut) > 10) && !(combinedTimeIsOk &&
std::abs(combinedTime.timeAtIpInOut) < 10))
1024 if (combinedTimeIsOk && (combinedTime.timeAtIpInOut > 20 || combinedTime.timeAtIpInOut < -45))
1032 bool run2016_hip_mitigation) {
1036 double chIso =
muon.pfIsolationR04().sumChargedHadronPt;
1037 double nIso =
muon.pfIsolationR04().sumNeutralHadronEt;
1038 double phoIso =
muon.pfIsolationR04().sumPhotonEt;
1039 double puIso =
muon.pfIsolationR04().sumPUPt;
1040 double dbCorrectedIsolation = chIso +
std::max(nIso + phoIso - .5 * puIso, 0.);
1041 double dbCorrectedRelIso = dbCorrectedIsolation /
muon.pt();
1065 if (dbCorrectedRelIso < 0.40)
1067 if (dbCorrectedRelIso < 0.25)
1069 if (dbCorrectedRelIso < 0.20)
1071 if (dbCorrectedRelIso < 0.15)
1073 if (dbCorrectedRelIso < 0.10)
1075 if (dbCorrectedRelIso < 0.05)
double pt() const final
transverse momentum
reco::Muon::Selector value
bool isMediumMuon(const reco::Muon &, bool run2016_hip_mitigation=false)
ret
prodAgent to be discontinued
reco::Muon::Selector makeSelectorBitset(reco::Muon const &muon, reco::Vertex const *vertex=nullptr, bool run2016_hip_mitigation=false)
float caloCompatibility(const reco::Muon &muon)
bool isLooseMuon(const reco::Muon &)
SelectionType
Selector type.
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
ArbitrationType
define arbitration schemes
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Abs< T >::type abs(const T &t)
float segmentCompatibility(const reco::Muon &muon, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
bool isSoftMuon(const reco::Muon &, const reco::Vertex &, bool run2016_hip_mitigation=false)
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
int sharedSegments(const reco::Muon &muon1, const reco::Muon &muon2, unsigned int segmentArbitrationMask=reco::MuonSegmentMatch::BestInChamberByDR)
bool isHighPtMuon(const reco::Muon &, const reco::Vertex &)
SelectionType selectionTypeFromString(const std::string &label)
const reco::Muon::ArbitrationType arbitrationType
unsigned int RequiredStationMask(const reco::Muon &muon, double maxChamberDist, double maxChamberDistPull, reco::Muon::ArbitrationType arbitrationType)
std::vector< MuonChamberMatch > & matches()
get muon matching information
static const SelectorStringToEnum selectorStringToEnumMap[]
reco::Muon::Selector selectorFromString(const std::string &label)
bool outOfTimeMuon(const reco::Muon &muon)
bool isTrackerHighPtMuon(const reco::Muon &, const reco::Vertex &)
bool isTightMuon(const reco::Muon &, const reco::Vertex &)
bool isLooseTriggerMuon(const reco::Muon &)
static const SelectionTypeStringToEnum selectionTypeStringToEnumMap[]