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 int nr_of_stations_with_segment = 0;
67 std::vector<int> stations_w_track(8);
68 std::vector<int> station_has_segmentmatch(8);
69 std::vector<int> station_was_crossed(8);
70 std::vector<float> stations_w_track_at_boundary(8);
71 std::vector<float> station_weight(8);
72 int position_in_stations = 0;
73 float full_weight = 0.;
75 for (
int i = 1;
i <= 8; ++
i) {
81 if (thisTrackDist < 999999) {
82 ++nr_of_stations_crossed;
83 station_was_crossed[
i - 1] = 1;
84 if (thisTrackDist > -10.)
85 stations_w_track_at_boundary[
i - 1] = thisTrackDist;
87 stations_w_track_at_boundary[
i - 1] = 0.;
91 ++nr_of_stations_with_segment;
92 station_has_segmentmatch[
i - 1] = 1;
96 if (thisTrackDist < 999999) {
97 ++nr_of_stations_crossed;
98 station_was_crossed[
i - 1] = 1;
99 if (thisTrackDist > -10.)
100 stations_w_track_at_boundary[
i - 1] = thisTrackDist;
102 stations_w_track_at_boundary[
i - 1] = 0.;
106 ++nr_of_stations_with_segment;
107 station_has_segmentmatch[
i - 1] = 1;
126 const float attenuate_weight_regain = 0.5;
128 for (
int i = 1;
i <= 8; ++
i) {
134 if (station_was_crossed[
i - 1] > 0) {
140 ++position_in_stations;
142 switch (nr_of_stations_crossed) {
144 station_weight[
i - 1] = 1.f;
147 if (position_in_stations == 1)
148 station_weight[
i - 1] = 0.33f;
150 station_weight[
i - 1] = 0.67f;
153 if (position_in_stations == 1)
154 station_weight[
i - 1] = 0.23f;
155 else if (position_in_stations == 2)
156 station_weight[
i - 1] = 0.33f;
158 station_weight[
i - 1] = 0.44f;
161 if (position_in_stations == 1)
162 station_weight[
i - 1] = 0.10f;
163 else if (position_in_stations == 2)
164 station_weight[
i - 1] = 0.20f;
165 else if (position_in_stations == 3)
166 station_weight[
i - 1] = 0.30f;
168 station_weight[
i - 1] = 0.40f;
175 station_weight[
i - 1] = 1.f / nr_of_stations_crossed;
178 if (use_weight_regain_at_chamber_boundary) {
179 if (station_has_segmentmatch[
i - 1] <= 0 && stations_w_track_at_boundary[
i - 1] != 0.) {
184 station_weight[
i - 1] = station_weight[
i - 1] * attenuate_weight_regain * 0.5f *
185 (std::erf(stations_w_track_at_boundary[
i - 1] / 6.
f) + 1.f);
186 }
else if (station_has_segmentmatch[
i - 1] <= 0 &&
187 stations_w_track_at_boundary[
i - 1] == 0.
f) {
189 station_weight[
i - 1] = 0.f;
192 if (station_has_segmentmatch[
i - 1] <= 0)
193 station_weight[
i - 1] = 0.f;
197 if (station_has_segmentmatch[
i - 1] > 0) {
201 const float pullTot2 =
203 if (pullTot2 > 1.
f) {
207 if (use_match_dist_penalty) {
209 if (dxy2 < 9.f && pullTot2 > 9.
f) {
211 station_weight[
i - 1] *= 1.f /
std::pow(dxy2, .125);
213 station_weight[
i - 1] *= 1.f /
std::pow(pullTot2, .125);
221 if (use_match_dist_penalty) {
235 if (use_match_dist_penalty) {
247 const float pullTot2 =
249 if (pullTot2 > 1.
f) {
251 if (use_match_dist_penalty) {
255 if (dxy2 < 9.f && pullTot2 > 9.
f) {
257 station_weight[
i - 1] *= 1.f /
std::pow(dxy2, .125);
259 station_weight[
i - 1] *= 1.f /
std::pow(pullTot2, .125);
271 station_weight[
i - 1] = 0.f;
275 full_weight += station_weight[
i - 1];
281 if (nr_of_stations_crossed == 0) {
295 double minCompatibility,
297 if (!
muon.isMatchesValid())
299 bool goodMuon =
false;
325 double maxChamberDist,
326 double maxChamberDistPull,
328 bool syncMinNMatchesNRequiredStationsInBarrelOnly,
329 bool applyAlsoAngularCuts) {
330 if (!
muon.isMatchesValid())
332 bool goodMuon =
false;
341 unsigned int theRequiredStationMask =
346 int numRequiredStations = 0;
347 for (
int it = 0; it < 8; ++it) {
348 if (theStationMask & 1 << it)
350 if (theRequiredStationMask & 1 << it)
351 ++numRequiredStations;
356 if (syncMinNMatchesNRequiredStationsInBarrelOnly) {
379 if (theRequiredStationMask) {
380 for (
int stationIdx = 7; stationIdx >= 0; --stationIdx)
381 if (theRequiredStationMask & 1 << stationIdx) {
382 if (theStationMask & 1 << stationIdx) {
383 lastSegBit = stationIdx;
392 for (
int stationIdx = 7; stationIdx >= 0; --stationIdx)
393 if (theStationMask & 1 << stationIdx) {
394 lastSegBit = stationIdx;
404 station = lastSegBit < 4 ? lastSegBit + 1 : lastSegBit - 3;
442 for (
int stationIdx =
station; stationIdx > 0; --stationIdx) {
443 if (!(theStationMask & 1 << (stationIdx - 1)))
488 bool existsGoodDTSegX =
false;
489 bool existsDTSegY =
false;
493 for (
int stationIdx = 0; stationIdx <= 7; ++stationIdx)
494 if (theStationMask & 1 << stationIdx) {
495 station = stationIdx < 4 ? stationIdx + 1 : stationIdx - 3;
503 existsGoodDTSegX =
true;
540 else if (existsGoodDTSegX)
551 for (
const auto& chamberMatch :
muon.matches()) {
555 const float trkX = chamberMatch.x;
556 const float errX = chamberMatch.xErr;
558 for (
const auto& rpcMatch : chamberMatch.rpcMatches) {
559 const float rpcX = rpcMatch.x;
560 const float dX =
std::abs(rpcX - trkX);
579 for (
const auto& chamberMatch :
muon.matches()) {
583 const float trkX = chamberMatch.x;
584 const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
585 const float trkY = chamberMatch.y;
586 const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
588 for (
const auto& segment : chamberMatch.me0Matches) {
589 const float me0X = segment.x;
590 const float me0ErrX2 = segment.xErr * segment.xErr;
591 const float me0Y = segment.y;
592 const float me0ErrY2 = segment.yErr * segment.yErr;
594 const float dX =
std::abs(me0X - trkX);
595 const float dY =
std::abs(me0Y - trkY);
596 const float invPullX2 = errX2 + me0ErrX2;
597 const float invPullY2 = errY2 + me0ErrY2;
615 for (
const auto& chamberMatch :
muon.matches()) {
619 const float trkX = chamberMatch.x;
620 const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
621 const float trkY = chamberMatch.y;
622 const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
624 for (
const auto& segment : chamberMatch.gemMatches) {
625 const float gemX = segment.x;
626 const float gemErrX2 = segment.xErr * segment.xErr;
627 const float gemY = segment.y;
628 const float gemErrY2 = segment.yErr * segment.yErr;
630 const float dX =
std::abs(gemX - trkX);
631 const float dY =
std::abs(gemY - trkY);
632 const float invPullX2 = errX2 + gemErrX2;
633 const float invPullY2 = errY2 + gemErrY2;
655 return muon.isGlobalMuon();
658 return muon.isTrackerMuon();
661 return muon.isStandAloneMuon();
670 return muon.isGlobalMuon() &&
muon.globalTrack()->normalizedChi2() < 10. &&
671 muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0;
684 return muon.isTrackerMuon() &&
685 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
true,
false);
688 return muon.isTrackerMuon() &&
689 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
true,
false);
692 return muon.isTrackerMuon() &&
693 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
696 return muon.isTrackerMuon() &&
697 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
701 return muon.isTrackerMuon() &&
702 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
704 return muon.isTrackerMuon() &&
705 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
false,
false);
709 return muon.isTrackerMuon() &&
710 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
712 return muon.isTrackerMuon() &&
713 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
false,
false);
724 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
725 std::abs(
muon.combinedQuality().trkRelChi2 -
muon.innerTrack()->normalizedChi2()) < 2.0;
728 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
729 std::abs(
muon.combinedQuality().staRelChi2 -
muon.outerTrack()->normalizedChi2()) < 2.0;
732 return muon.isGlobalMuon() &&
muon.isQualityValid() &&
muon.combinedQuality().trkKink < 100.0;
735 return muon.isTrackerMuon() &&
736 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
false,
true);
739 return muon.isTrackerMuon() &&
740 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
false,
true);
743 return muon.isTrackerMuon() &&
744 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
true);
747 return muon.isTrackerMuon() &&
748 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
true);
752 return muon.isTrackerMuon() &&
753 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9,
arbitrationType,
false,
false);
755 return muon.isTrackerMuon() &&
756 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3,
arbitrationType,
true,
false);
760 return muon.isTrackerMuon() &&
761 isGoodMuon(
muon,
TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9,
arbitrationType,
false,
false);
763 return muon.isTrackerMuon() &&
764 isGoodMuon(
muon,
TMLastStation, 2, 3, 3, 3, 3, -3, -3,
arbitrationType,
true,
false);
767 return muon.isRPCMuon() &&
isGoodMuon(
muon,
RPCMu, 2, 20, 4, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
770 return muon.isME0Muon();
773 return muon.isME0Muon() &&
774 isGoodMuon(
muon,
ME0Mu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
777 return muon.isGEMMuon();
780 return muon.isGEMMuon() &&
781 isGoodMuon(
muon,
GEMMu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9,
arbitrationType,
false,
false);
792 const reco::Muon& muon1,
const reco::Muon& muon2,
double pullX,
double pullY,
bool checkAdjacentChambers) {
795 unsigned int betterMuon = (muon1.
pt() > muon2.
pt() ? 1 : 2);
796 for (std::vector<reco::MuonChamberMatch>::const_iterator chamber1 = muon1.
matches().begin();
797 chamber1 != muon1.
matches().end();
799 for (std::vector<reco::MuonChamberMatch>::const_iterator chamber2 = muon2.
matches().begin();
800 chamber2 != muon2.
matches().end();
806 if (chamber1->id == chamber2->id) {
808 if (
std::abs(chamber1->x - chamber2->x) <
809 pullX *
sqrt(chamber1->xErr * chamber1->xErr + chamber2->xErr * chamber2->xErr)) {
814 if (nMatches1 == 0 || nMatches2 == 0)
818 if (
std::abs(chamber1->y - chamber2->y) <
819 pullY *
sqrt(chamber1->yErr * chamber1->yErr + chamber2->yErr * chamber2->yErr)) {
824 if (nMatches1 == 0 || nMatches2 == 0)
828 if (!checkAdjacentChambers)
835 if (
id1.endcap() !=
id2.endcap())
837 if (
id1.station() !=
id2.station())
839 if (
id1.ring() !=
id2.ring())
849 if (
std::abs(chamber1->edgeX) > chamber1->xErr * pullX)
851 if (
std::abs(chamber2->edgeX) > chamber2->xErr * pullX)
853 if (chamber1->x * chamber2->x < 0) {
858 if (nMatches1 == 0 || nMatches2 == 0)
873 bool layer_requirements =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
874 muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
875 bool match_requirements =
876 (
muon.expectedNnumberOfMatchedStations() < 2)
or (
muon.numberOfMatchedStations() > 1)
or (
muon.pt() < 8);
877 return layer_requirements and match_requirements;
881 if (!
muon.isPFMuon() || !
muon.isGlobalMuon())
886 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
887 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
892 return muID &&
hits && ip;
896 return muon.isPFMuon() && (
muon.isGlobalMuon() ||
muon.isTrackerMuon());
902 if (run2016_hip_mitigation) {
903 if (
muon.innerTrack()->validFraction() < 0.49)
906 if (
muon.innerTrack()->validFraction() < 0.8)
910 bool goodGlb =
muon.isGlobalMuon() &&
muon.globalTrack()->normalizedChi2() < 3. &&
911 muon.combinedQuality().chi2LocalPosition < 12. &&
muon.combinedQuality().trkKink < 20.;
922 bool layers =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
923 muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
930 return layers && ip && (ishighq | run2016_hip_mitigation);
934 if (!
muon.isGlobalMuon())
937 bool muValHits = (
muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 ||
938 muon.tunePMuonBestTrack()->hitPattern().numberOfValidMuonHits() > 0);
940 bool muMatchedSt =
muon.numberOfMatchedStations() > 1;
942 if (
muon.isTrackerMuon() &&
muon.numberOfMatchedStations() == 1) {
943 if (
muon.expectedNnumberOfMatchedStations() < 2 || !(
muon.stationMask() == 1 ||
muon.stationMask() == 16) ||
944 muon.numberOfMatchedRPCLayers() > 2)
949 bool muID = muValHits && muMatchedSt;
951 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
952 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
954 bool momQuality =
muon.tunePMuonBestTrack()->ptError() /
muon.tunePMuonBestTrack()->pt() < 0.3;
959 return muID &&
hits && momQuality && ip;
963 bool muID =
muon.isTrackerMuon() &&
muon.track().isNonnull() && (
muon.numberOfMatchedStations() > 1);
967 bool hits =
muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
968 muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
970 bool momQuality =
muon.tunePMuonBestTrack()->ptError() < 0.3 *
muon.tunePMuonBestTrack()->pt();
975 return muID &&
hits && momQuality && ip;
982 for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch =
mu.matches().begin();
983 chamberMatch !=
mu.matches().end();
985 if (chamberMatch->segmentMatches.empty())
987 for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch2 = mu2.
matches().begin();
988 chamberMatch2 != mu2.
matches().end();
990 if (chamberMatch2->segmentMatches.empty())
992 if (chamberMatch2->id() != chamberMatch->id())
994 for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch = chamberMatch->segmentMatches.begin();
995 segmentMatch != chamberMatch->segmentMatches.end();
997 if (!segmentMatch->isMask(segmentArbitrationMask))
999 for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch2 = chamberMatch2->segmentMatches.begin();
1000 segmentMatch2 != chamberMatch2->segmentMatches.end();
1002 if (!segmentMatch2->isMask(segmentArbitrationMask))
1004 if ((segmentMatch->cscSegmentRef.isNonnull() &&
1005 segmentMatch->cscSegmentRef == segmentMatch2->cscSegmentRef) ||
1006 (segmentMatch->dtSegmentRef.isNonnull() && segmentMatch->dtSegmentRef == segmentMatch2->dtSegmentRef)) {
1018 const auto& combinedTime =
muon.time();
1019 const auto& rpcTime =
muon.rpcTime();
1020 bool combinedTimeIsOk = (combinedTime.nDof > 7);
1021 bool rpcTimeIsOk = (rpcTime.nDof > 1 &&
std::abs(rpcTime.timeAtIpInOutErr) < 0.001);
1022 bool outOfTime =
false;
1024 if ((
std::abs(rpcTime.timeAtIpInOut) > 10) && !(combinedTimeIsOk &&
std::abs(combinedTime.timeAtIpInOut) < 10))
1027 if (combinedTimeIsOk && (combinedTime.timeAtIpInOut > 20 || combinedTime.timeAtIpInOut < -45))
1035 bool run2016_hip_mitigation) {
1039 double chIso =
muon.pfIsolationR04().sumChargedHadronPt;
1040 double nIso =
muon.pfIsolationR04().sumNeutralHadronEt;
1041 double phoIso =
muon.pfIsolationR04().sumPhotonEt;
1042 double puIso =
muon.pfIsolationR04().sumPUPt;
1043 double dbCorrectedIsolation = chIso +
std::max(nIso + phoIso - .5 * puIso, 0.);
1044 double dbCorrectedRelIso = dbCorrectedIsolation /
muon.pt();
1068 if (dbCorrectedRelIso < 0.40)
1070 if (dbCorrectedRelIso < 0.25)
1072 if (dbCorrectedRelIso < 0.20)
1074 if (dbCorrectedRelIso < 0.15)
1076 if (dbCorrectedRelIso < 0.10)
1078 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 &)
Power< A, B >::type pow(const A &a, const B &b)
static const SelectionTypeStringToEnum selectionTypeStringToEnumMap[]