36 propagatorToken_(esConsumes(
edm::
ESInputTag(
"",
"SteppingHelixPropagatorAny"))) {
37 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: Constructor called";
39 produces<reco::MuonCollection>();
40 produces<reco::CaloMuonCollection>();
41 produces<reco::MuonTimeExtraMap>(
"combined");
42 produces<reco::MuonTimeExtraMap>(
"dt");
43 produces<reco::MuonTimeExtraMap>(
"csc");
73 iConfig.
getParameter<
double>(
"ptThresholdToFillCandidateP4WithGlobalFit");
75 iConfig.
getParameter<
double>(
"sigmaThresholdToFillCandidateP4WithGlobalFit");
86 theTimingFiller_ = std::make_unique<MuonTimingFiller>(timingParameters, consumesCollector());
91 theShowerDigiFiller_ = std::make_unique<MuonShowerDigiFiller>(showerDigiParameters, consumesCollector());
134 <<
"Number of input collection labels is different from number of types. "
135 <<
"For each collection label there should be exactly one collection type specified.";
137 throw cms::Exception(
"ConfigurationError") <<
"Number of input collections should be from 1 to 7.";
142 <<
"========================================================================\n"
143 <<
"Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
144 <<
"========================================================================\n";
147 glbQualToken_ = consumes<edm::ValueMap<reco::MuonQuality> >(glbQualTag);
159 rpcHitToken_ = consumes<RPCRecHitCollection>(rpcHitTag);
257 LogTrace(
"MuonIdentification") <<
"Creating a muon from a track " <<
track.get()->pt()
258 <<
" Pt (GeV), eta: " <<
track.get()->eta();
261 LogTrace(
"MuonIdentification") <<
"Muon created from a track ";
264 aMuon.setBestTrack(
type);
265 aMuon.setTunePBestTrack(
type);
268 <<
"Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
274 LogTrace(
"MuonIdentification") <<
"Creating a CaloMuon from a Muon";
279 if (
muon.isEnergyValid())
288 LogTrace(
"MuonIdentification") <<
"Creating a muon from a link to tracks object";
295 bool useSigmaSwitch =
false;
303 if (tpfmsRef.
isNull() && pickyRef.isNull() && dytRef.isNull()) {
304 edm::LogWarning(
"MakeMuonWithTEV") <<
"Failed to get TEV refits, fall back to sigma switch.";
305 useSigmaSwitch =
true;
308 useSigmaSwitch =
true;
311 if (useSigmaSwitch) {
313 links.trackerTrack(),
318 links.trackerTrack(),
324 aMuon =
makeMuon(*chosenTrack.first);
353 const double p =
track.p();
356 LogTrace(
"MuonIdentification") <<
"Skipped low momentum track (Pt,P): " <<
pt <<
", " <<
track.p() <<
" GeV";
364 LogTrace(
"MuonIdentification") <<
"Skipped track with large pseudo rapidity (Eta: " <<
track.eta() <<
" )";
375 const auto subdetId =
id.subdetId();
386 if (!
muon.isMatchesValid() ||
track.extra().isNull() ||
track.extra()->recHitsSize() == 0)
389 int numberOfCommonDetIds = 0;
390 const std::vector<reco::MuonChamberMatch>&
matches(
muon.matches());
392 if (
match.segmentMatches.empty())
395 bool foundCommonDetId =
false;
396 for (
auto hit =
track.extra()->recHitsBegin();
hit !=
track.extra()->recHitsEnd(); ++
hit) {
402 foundCommonDetId =
true;
406 if (foundCommonDetId) {
407 ++numberOfCommonDetIds;
411 return numberOfCommonDetIds;
422 const int nHitsGood = goodMuon.
globalTrack()->hitPattern().numberOfValidMuonHits();
423 const int nHitsBad = badMuon.
globalTrack()->hitPattern().numberOfValidMuonHits();
424 if (
std::min(nHitsGood, nHitsBad) > 10) {
425 const double chi2Good = goodMuon.
globalTrack()->normalizedChi2();
426 const double chi2Bad = badMuon.
globalTrack()->normalizedChi2();
427 return (chi2Good <= chi2Bad);
430 return (nHitsGood >= nHitsBad);
434 auto outputMuons = std::make_unique<reco::MuonCollection>();
435 auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
447 outputMuons->push_back(
muon);
454 std::vector<bool> goodmuons(nLink,
true);
457 for (
unsigned int i = 0;
i < nLink - 1; ++
i) {
459 if (iLink.trackerTrack().isNull() || !
checkLinks(&iLink))
461 for (
unsigned int j =
i + 1;
j < nLink; ++
j) {
465 if (iLink.trackerTrack() == jLink.trackerTrack()) {
471 goodmuons[
j] =
false;
473 goodmuons[
i] =
false;
478 for (
unsigned int i = 0;
i < nLink - 1; ++
i) {
482 if (iLink.standAloneTrack().isNull() || !
checkLinks(&iLink))
484 for (
unsigned int j =
i + 1;
j < nLink; ++
j) {
490 if (iLink.standAloneTrack() == jLink.standAloneTrack()) {
492 goodmuons[
j] =
false;
494 goodmuons[
i] =
false;
499 for (
unsigned int i = 0;
i < nLink; ++
i) {
507 for (
const auto&
muon : *outputMuons) {
508 if (
muon.track() == iLink.trackerTrack() &&
muon.standAloneMuon() == iLink.standAloneTrack() &&
509 muon.combinedMuon() == iLink.globalTrack()) {
515 outputMuons->push_back(
makeMuon(iLink));
523 LogTrace(
"MuonIdentification") <<
"Creating tracker muons";
524 std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
534 bool splitTrack =
false;
537 const auto&
directions = splitTrack ? directions1 : directions2;
566 for (
auto&
muon : *outputMuons) {
584 LogTrace(
"MuonIdentification") <<
"Found a corresponding global muon. Set energy, matches and move on";
589 if (goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon) {
592 LogTrace(
"MuonIdentification") <<
"track failed minimal number of muon matches requirement";
604 LogTrace(
"MuonIdentification") <<
"Looking for new muons among stand alone muon tracks";
610 for (
auto&
muon : *outputMuons) {
611 if (!
muon.standAloneMuon().isNull()) {
613 if (
muon.standAloneMuon().get() == &outerTrack) {
626 LogTrace(
"MuonIdentification") <<
"Found associated tracker muon. Set a reference and move on";
635 LogTrace(
"MuonIdentification") <<
"No associated stand alone track is found. Making a muon";
636 outputMuons->push_back(
648 LogTrace(
"MuonIdentification") <<
"Dress up muons if it's necessary";
650 const int nMuons = outputMuons->size();
652 std::vector<reco::MuonTimeExtra> dtTimeColl(
nMuons);
653 std::vector<reco::MuonTimeExtra> cscTimeColl(
nMuons);
654 std::vector<reco::MuonTimeExtra> combinedTimeColl(
nMuons);
655 std::vector<reco::IsoDeposit> trackDepColl(
nMuons);
656 std::vector<reco::IsoDeposit> ecalDepColl(
nMuons);
657 std::vector<reco::IsoDeposit> hcalDepColl(
nMuons);
658 std::vector<reco::IsoDeposit> hoDepColl(
nMuons);
659 std::vector<reco::IsoDeposit> jetDepColl(
nMuons);
662 for (
unsigned int i = 0;
i < outputMuons->size(); ++
i) {
663 auto&
muon = outputMuons->at(
i);
669 if (
muon.isStandAloneMuon()) {
676 LogTrace(
"MuonIdentification") <<
"THIS SHOULD NEVER HAPPEN";
696 iEvent, iSetup,
muon, trackDepColl[
i], ecalDepColl[
i], hcalDepColl[
i], hoDepColl[
i], jetDepColl[
i]);
708 muonTime.
nDof = combinedTime.
nDof();
714 muon.setTime(muonTime);
715 muon.setRPCTime(rpcTime);
716 dtTimeColl[
i] = dtTime;
717 cscTimeColl[
i] = cscTime;
718 combinedTimeColl[
i] = combinedTime;
721 LogTrace(
"MuonIdentification") <<
"number of muons produced: " << outputMuons->size();
731 auto oMap = std::make_unique<MapType>();
733 typename MapType::Filler
filler(*oMap);
734 filler.insert(refH, vec.begin(), vec.end());
740 fillMap(muonHandle, combinedTimeColl,
iEvent,
"combined");
741 fillMap(muonHandle, dtTimeColl,
iEvent,
"dt");
742 fillMap(muonHandle, cscTimeColl,
iEvent,
"csc");
796 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId";
806 <<
"Failed to fill muon id information for a muon with undefined references to tracks";
810 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = " <<
fillEnergy_;
825 for (
auto hit :
info.crossedHcalRecHits) {
836 if (!
info.crossedEcalIds.empty())
838 if (!
info.crossedHcalIds.empty())
842 for (
const auto&
hit :
info.ecalRecHits) {
843 if (
hit->
id() != emMaxId)
849 for (
const auto&
hit :
info.hcalRecHits) {
850 if (
hit->
id() != hadMaxId)
861 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
862 std::vector<reco::MuonChamberMatch> muonChamberMatches;
863 unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
869 const auto& lErr =
chamber.tState.localError();
870 const auto& lPos =
chamber.tState.localPosition();
871 const auto& lDir =
chamber.tState.localDirection();
873 const auto& localError = lErr.positionError();
874 matchedChamber.
x = lPos.x();
875 matchedChamber.
y = lPos.y();
876 matchedChamber.
xErr =
sqrt(localError.xx());
877 matchedChamber.
yErr =
sqrt(localError.yy());
879 matchedChamber.
dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
880 matchedChamber.
dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
883 matchedChamber.
dXdZErr = trajectoryCovMatrix(1, 1) > 0 ?
sqrt(trajectoryCovMatrix(1, 1)) : 0;
884 matchedChamber.
dYdZErr = trajectoryCovMatrix(2, 2) > 0 ?
sqrt(trajectoryCovMatrix(2, 2)) : 0;
898 ++nubmerOfMatchesAccordingToTrackAssociator;
901 for (
const auto& segment :
chamber.segments) {
903 matchedSegment.
x = segment.segmentLocalPosition.x();
904 matchedSegment.
y = segment.segmentLocalPosition.y();
905 matchedSegment.
dXdZ =
906 segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.x() / segment.segmentLocalDirection.z() : 0;
907 matchedSegment.
dYdZ =
908 segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.y() / segment.segmentLocalDirection.z() : 0;
909 matchedSegment.
xErr = segment.segmentLocalErrorXX > 0 ?
sqrt(segment.segmentLocalErrorXX) : 0;
910 matchedSegment.
yErr = segment.segmentLocalErrorYY > 0 ?
sqrt(segment.segmentLocalErrorYY) : 0;
911 matchedSegment.
dXdZErr = segment.segmentLocalErrorDxDz > 0 ?
sqrt(segment.segmentLocalErrorDxDz) : 0;
912 matchedSegment.
dYdZErr = segment.segmentLocalErrorDyDz > 0 ?
sqrt(segment.segmentLocalErrorDyDz) : 0;
913 matchedSegment.
t0 = segment.t0;
914 matchedSegment.
mask = 0;
919 matchedSegment.
hasZed_ = segment.hasZed;
920 matchedSegment.
hasPhi_ = segment.hasPhi;
922 bool matchedX =
false;
923 bool matchedY =
false;
924 LogTrace(
"MuonIdentification") <<
" matching local x, segment x: " << matchedSegment.
x
925 <<
", chamber x: " << matchedChamber.
x <<
", max: " <<
maxAbsDx_;
926 LogTrace(
"MuonIdentification") <<
" matching local y, segment y: " << matchedSegment.
y
927 <<
", chamber y: " << matchedChamber.
y <<
", max: " <<
maxAbsDy_;
928 const double matchedSegChDx =
std::abs(matchedSegment.
x - matchedChamber.
x);
929 const double matchedSegChDy =
std::abs(matchedSegment.
y - matchedChamber.
y);
930 if (matchedSegment.
xErr > 0 && matchedChamber.
xErr > 0)
931 LogTrace(
"MuonIdentification") <<
" xpull: "
934 if (matchedSegment.
yErr > 0 && matchedChamber.
yErr > 0)
935 LogTrace(
"MuonIdentification") <<
" ypull: "
941 else if (matchedSegment.
xErr > 0 && matchedChamber.
xErr > 0) {
943 if (matchedSegChDx * matchedSegChDx <
maxAbsPullX2_ * invMatchedSegChPullX2)
948 else if (matchedSegment.
yErr > 0 && matchedChamber.
yErr > 0) {
950 if (matchedSegChDy * matchedSegChDy <
maxAbsPullY2_ * invMatchedSegChPullY2)
953 if (matchedX && matchedY) {
955 matchedChamber.
me0Matches.push_back(matchedSegment);
957 matchedChamber.
gemMatches.push_back(matchedSegment);
962 muonChamberMatches.push_back(matchedChamber);
966 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
971 const auto& lErr =
chamber.tState.localError();
972 const auto& lPos =
chamber.tState.localPosition();
973 const auto& lDir =
chamber.tState.localDirection();
978 matchedChamber.
x = lPos.x();
979 matchedChamber.
y = lPos.y();
983 matchedChamber.
dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
984 matchedChamber.
dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
987 matchedChamber.
dXdZErr = trajectoryCovMatrix(1, 1) > 0 ?
sqrt(trajectoryCovMatrix(1, 1)) : 0;
988 matchedChamber.
dYdZErr = trajectoryCovMatrix(2, 2) > 0 ?
sqrt(trajectoryCovMatrix(2, 2)) : 0;
1000 if (rpcRecHit.rawId() !=
chamber.id.rawId())
1003 rpcHitMatch.
x = rpcRecHit.localPosition().x();
1004 rpcHitMatch.
mask = 0;
1005 rpcHitMatch.
bx = rpcRecHit.BunchX();
1007 const double absDx =
std::abs(rpcRecHit.localPosition().x() -
chamber.tState.localPosition().x());
1008 if (absDx <= 20
or absDx * absDx <= 16 * localError.
xx())
1009 matchedChamber.
rpcMatches.push_back(rpcHitMatch);
1012 muonChamberMatches.push_back(matchedChamber);
1018 LogTrace(
"MuonIdentification") <<
"number of muon chambers: " << aMuon.
matches().size() <<
"\n"
1019 <<
"number of chambers with segments according to the associator requirements: "
1020 << nubmerOfMatchesAccordingToTrackAssociator;
1021 LogTrace(
"MuonIdentification") <<
"number of segment matches with the producer requirements: "
1032 if (
muon->isTrackerMuon()) {
1038 if ((
muon->type() & (~mask)) == 0) {
1045 muon->setType(
muon->type() & (~
reco::Muon::TrackerMuon));
1057 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > chamberPairs;
1058 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > stationPairs;
1059 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> >
1063 for (
unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1) {
1064 auto& muon1 = pOutputMuons->at(muonIndex1);
1066 for (
auto& chamber1 : muon1.matches()) {
1068 std::vector<reco::MuonSegmentMatch>* segmentMatches1 =
getSegmentMatches(chamber1, muonType);
1070 if (segmentMatches1->empty())
1072 chamberPairs.clear();
1074 for (
auto& segment1 : *segmentMatches1) {
1075 chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1076 if (!segment1.isMask())
1078 arbitrationPairs.clear();
1079 arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1083 if (muon1.type() & muonType) {
1085 for (
unsigned int muonIndex2 = muonIndex1 + 1; muonIndex2 < pOutputMuons->size(); ++muonIndex2) {
1086 auto& muon2 = pOutputMuons->at(muonIndex2);
1088 if (!(muon2.type() & muonType))
1091 for (
auto& chamber2 : muon2.matches()) {
1093 std::vector<reco::MuonSegmentMatch>* segmentMatches2 =
getSegmentMatches(chamber2, muonType);
1094 for (
auto& segment2 : *segmentMatches2) {
1095 if (segment2.isMask())
1100 approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1101 approxEqual(segment2.dYdZErr, segment1.dYdZErr)) {
1102 arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1110 if (arbitrationPairs.empty())
1112 if (arbitrationPairs.size() == 1) {
1119 sort(arbitrationPairs.begin(),
1120 arbitrationPairs.end(),
1123 sort(arbitrationPairs.begin(),
1124 arbitrationPairs.end(),
1127 sort(arbitrationPairs.begin(),
1128 arbitrationPairs.end(),
1131 sort(arbitrationPairs.begin(),
1132 arbitrationPairs.end(),
1135 for (
auto& ap : arbitrationPairs) {
1144 for (
auto& segment2 : chamber1.segmentMatches) {
1145 if (segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull())
1147 if (
meshAlgo_->isDuplicateOf(segment1.cscSegmentRef, segment2.cscSegmentRef) &&
1148 (segment2.mask & 0x1e0000) && (segment1.mask & 0x1e0000)) {
1158 if (chamberPairs.empty())
1160 if (chamberPairs.size() == 1) {
1166 sort(chamberPairs.begin(),
1170 sort(chamberPairs.begin(),
1174 sort(chamberPairs.begin(),
1178 sort(chamberPairs.begin(),
1187 for (
int detectorIndex = 1; detectorIndex <= 5;
1190 stationPairs.clear();
1193 for (
auto&
chamber : muon1.matches()) {
1197 if (segmentMatches->empty())
1200 for (
auto& segment : *segmentMatches) {
1201 stationPairs.push_back(std::make_pair(&
chamber, &segment));
1205 if (stationPairs.empty())
1207 if (stationPairs.size() == 1) {
1213 sort(stationPairs.begin(),
1217 sort(stationPairs.begin(),
1221 sort(stationPairs.begin(),
1225 sort(stationPairs.begin(),
1257 <<
"Failed to compute muon isolation information for a muon with undefined references to tracks";
1266 if (caloDeps.size() != 3) {
1267 LogTrace(
"MuonIdentification") <<
"Failed to fill vector of calorimeter isolation deposits!";
1319 if (muonId.
sector() <= 12)
1321 if (muonId.
sector() == 13)
1323 if (muonId.
sector() == 14)
1336 if (
muon.isStandAloneMuon())
1337 return muon.standAloneMuon()->innerPosition().phi();
1339 if (
muon.matches().empty()) {
1340 if (
muon.innerTrack().isAvailable() &&
muon.innerTrack()->extra().isAvailable())
1341 return muon.innerTrack()->outerPosition().phi();
1370 const bool trackBAD =
links->trackerTrack().isNull();
1371 const bool staBAD =
links->standAloneTrack().isNull();
1372 const bool glbBAD =
links->globalTrack().isNull();
1373 if (trackBAD || staBAD || glbBAD) {
1374 edm::LogWarning(
"muonIDbadLinks") <<
"Global muon links to constituent tracks are invalid: trkBad " << trackBAD
1375 <<
" standaloneBad " << staBAD <<
" globalBad " << glbBAD
1376 <<
". There should be no such object. Muon is skipped.";
1384 desc.setAllowAnything();
1386 desc.add<
bool>(
"arbitrateTrackerMuons",
false);
1387 desc.add<
bool>(
"storeCrossedHcalRecHits",
false);
1388 desc.add<
bool>(
"fillShowerDigis",
false);
1393 descTrkAsoPar.add<
bool>(
"useGEM",
false);
1394 descTrkAsoPar.add<
bool>(
"useME0",
false);
1395 descTrkAsoPar.setAllowAnything();