36 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: Constructor called";
38 produces<reco::MuonCollection>();
39 produces<reco::CaloMuonCollection>();
40 produces<reco::MuonTimeExtraMap>(
"combined");
41 produces<reco::MuonTimeExtraMap>(
"dt");
42 produces<reco::MuonTimeExtraMap>(
"csc");
70 iConfig.
getParameter<
double>(
"ptThresholdToFillCandidateP4WithGlobalFit");
72 iConfig.
getParameter<
double>(
"sigmaThresholdToFillCandidateP4WithGlobalFit");
83 theTimingFiller_ = std::make_unique<MuonTimingFiller>(timingParameters, consumesCollector());
88 theShowerDigiFiller_ = std::make_unique<MuonShowerDigiFiller>(showerDigiParameters, consumesCollector());
131 <<
"Number of input collection labels is different from number of types. "
132 <<
"For each collection label there should be exactly one collection type specified.";
134 throw cms::Exception(
"ConfigurationError") <<
"Number of input collections should be from 1 to 7.";
139 <<
"========================================================================\n"
140 <<
"Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
141 <<
"========================================================================\n";
144 glbQualToken_ = consumes<edm::ValueMap<reco::MuonQuality> >(glbQualTag);
156 rpcHitToken_ = consumes<RPCRecHitCollection>(rpcHitTag);
256 LogTrace(
"MuonIdentification") <<
"Creating a muon from a track " <<
track.get()->pt()
257 <<
" Pt (GeV), eta: " <<
track.get()->eta();
260 LogTrace(
"MuonIdentification") <<
"Muon created from a track ";
263 aMuon.setBestTrack(
type);
264 aMuon.setTunePBestTrack(
type);
267 <<
"Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
273 LogTrace(
"MuonIdentification") <<
"Creating a CaloMuon from a Muon";
278 if (
muon.isEnergyValid())
287 LogTrace(
"MuonIdentification") <<
"Creating a muon from a link to tracks object";
294 bool useSigmaSwitch =
false;
302 if (tpfmsRef.
isNull() && pickyRef.isNull() && dytRef.isNull()) {
303 edm::LogWarning(
"MakeMuonWithTEV") <<
"Failed to get TEV refits, fall back to sigma switch.";
304 useSigmaSwitch =
true;
307 useSigmaSwitch =
true;
310 if (useSigmaSwitch) {
312 links.trackerTrack(),
317 links.trackerTrack(),
323 aMuon =
makeMuon(*chosenTrack.first);
352 const double p =
track.p();
355 LogTrace(
"MuonIdentification") <<
"Skipped low momentum track (Pt,P): " <<
pt <<
", " <<
track.p() <<
" GeV";
363 LogTrace(
"MuonIdentification") <<
"Skipped track with large pseudo rapidity (Eta: " <<
track.eta() <<
" )";
374 const auto subdetId =
id.subdetId();
385 if (!
muon.isMatchesValid() ||
track.extra().isNull() ||
track.extra()->recHitsSize() == 0)
388 int numberOfCommonDetIds = 0;
389 const std::vector<reco::MuonChamberMatch>&
matches(
muon.matches());
391 if (
match.segmentMatches.empty())
394 bool foundCommonDetId =
false;
395 for (
auto hit =
track.extra()->recHitsBegin();
hit !=
track.extra()->recHitsEnd(); ++
hit) {
401 foundCommonDetId =
true;
405 if (foundCommonDetId) {
406 ++numberOfCommonDetIds;
410 return numberOfCommonDetIds;
424 const int nHitsGood = goodMuon.
globalTrack()->hitPattern().numberOfValidMuonHits();
425 const int nHitsBad = badMuon.
globalTrack()->hitPattern().numberOfValidMuonHits();
426 if (
std::min(nHitsGood, nHitsBad) > 10) {
427 const double chi2Good = goodMuon.
globalTrack()->normalizedChi2();
428 const double chi2Bad = badMuon.
globalTrack()->normalizedChi2();
429 return (chi2Good <= chi2Bad);
432 return (nHitsGood >= nHitsBad);
436 auto outputMuons = std::make_unique<reco::MuonCollection>();
437 auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
449 outputMuons->push_back(
muon);
456 std::vector<bool> goodmuons(nLink,
true);
459 for (
unsigned int i = 0;
i < nLink - 1; ++
i) {
461 if (iLink.trackerTrack().isNull() || !
checkLinks(&iLink))
463 for (
unsigned int j =
i + 1;
j < nLink; ++
j) {
467 if (iLink.trackerTrack() == jLink.trackerTrack()) {
473 goodmuons[
j] =
false;
475 goodmuons[
i] =
false;
480 for (
unsigned int i = 0;
i < nLink - 1; ++
i) {
484 if (iLink.standAloneTrack().isNull() || !
checkLinks(&iLink))
486 for (
unsigned int j =
i + 1;
j < nLink; ++
j) {
492 if (iLink.standAloneTrack() == jLink.standAloneTrack()) {
494 goodmuons[
j] =
false;
496 goodmuons[
i] =
false;
501 for (
unsigned int i = 0;
i < nLink; ++
i) {
509 for (
auto muon : *outputMuons) {
510 if (
muon.track() == iLink.trackerTrack() &&
muon.standAloneMuon() == iLink.standAloneTrack() &&
511 muon.combinedMuon() == iLink.globalTrack()) {
517 outputMuons->push_back(
makeMuon(iLink));
525 LogTrace(
"MuonIdentification") <<
"Creating tracker muons";
526 std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
536 bool splitTrack =
false;
539 const auto&
directions = splitTrack ? directions1 : directions2;
568 for (
auto&
muon : *outputMuons) {
585 LogTrace(
"MuonIdentification") <<
"Found a corresponding global muon. Set energy, matches and move on";
590 if (goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon) {
593 LogTrace(
"MuonIdentification") <<
"track failed minimal number of muon matches requirement";
605 LogTrace(
"MuonIdentification") <<
"Looking for new muons among stand alone muon tracks";
611 for (
auto&
muon : *outputMuons) {
612 if (!
muon.standAloneMuon().isNull()) {
614 if (
muon.standAloneMuon().get() == &outerTrack) {
627 LogTrace(
"MuonIdentification") <<
"Found associated tracker muon. Set a reference and move on";
636 LogTrace(
"MuonIdentification") <<
"No associated stand alone track is found. Making a muon";
637 outputMuons->push_back(
649 LogTrace(
"MuonIdentification") <<
"Dress up muons if it's necessary";
651 const int nMuons = outputMuons->size();
653 std::vector<reco::MuonTimeExtra> dtTimeColl(
nMuons);
654 std::vector<reco::MuonTimeExtra> cscTimeColl(
nMuons);
655 std::vector<reco::MuonTimeExtra> combinedTimeColl(
nMuons);
656 std::vector<reco::IsoDeposit> trackDepColl(
nMuons);
657 std::vector<reco::IsoDeposit> ecalDepColl(
nMuons);
658 std::vector<reco::IsoDeposit> hcalDepColl(
nMuons);
659 std::vector<reco::IsoDeposit> hoDepColl(
nMuons);
660 std::vector<reco::IsoDeposit> jetDepColl(
nMuons);
663 for (
unsigned int i = 0;
i < outputMuons->size(); ++
i) {
664 auto&
muon = outputMuons->at(
i);
670 if (
muon.isStandAloneMuon()) {
677 LogTrace(
"MuonIdentification") <<
"THIS SHOULD NEVER HAPPEN";
697 iEvent, iSetup,
muon, trackDepColl[
i], ecalDepColl[
i], hcalDepColl[
i], hoDepColl[
i], jetDepColl[
i]);
709 muonTime.
nDof = combinedTime.
nDof();
715 muon.setTime(muonTime);
716 muon.setRPCTime(rpcTime);
717 dtTimeColl[
i] = dtTime;
718 cscTimeColl[
i] = cscTime;
719 combinedTimeColl[
i] = combinedTime;
722 LogTrace(
"MuonIdentification") <<
"number of muons produced: " << outputMuons->size();
732 auto oMap = std::make_unique<MapType>();
734 typename MapType::Filler
filler(*oMap);
735 filler.insert(refH, vec.begin(), vec.end());
741 fillMap(muonHandle, combinedTimeColl,
iEvent,
"combined");
742 fillMap(muonHandle, dtTimeColl,
iEvent,
"dt");
743 fillMap(muonHandle, cscTimeColl,
iEvent,
"csc");
797 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId";
807 <<
"Failed to fill muon id information for a muon with undefined references to tracks";
811 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = " <<
fillEnergy_;
826 for (
auto hit :
info.crossedHcalRecHits) {
837 if (!
info.crossedEcalIds.empty())
839 if (!
info.crossedHcalIds.empty())
843 for (
const auto&
hit :
info.ecalRecHits) {
844 if (
hit->
id() != emMaxId)
850 for (
const auto&
hit :
info.hcalRecHits) {
851 if (
hit->
id() != hadMaxId)
862 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
863 std::vector<reco::MuonChamberMatch> muonChamberMatches;
864 unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
870 const auto& lErr =
chamber.tState.localError();
871 const auto& lPos =
chamber.tState.localPosition();
872 const auto& lDir =
chamber.tState.localDirection();
874 const auto& localError = lErr.positionError();
875 matchedChamber.
x = lPos.x();
876 matchedChamber.
y = lPos.y();
877 matchedChamber.
xErr =
sqrt(localError.xx());
878 matchedChamber.
yErr =
sqrt(localError.yy());
880 matchedChamber.
dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
881 matchedChamber.
dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
884 matchedChamber.
dXdZErr = trajectoryCovMatrix(1, 1) > 0 ?
sqrt(trajectoryCovMatrix(1, 1)) : 0;
885 matchedChamber.
dYdZErr = trajectoryCovMatrix(2, 2) > 0 ?
sqrt(trajectoryCovMatrix(2, 2)) : 0;
899 ++nubmerOfMatchesAccordingToTrackAssociator;
902 for (
const auto& segment :
chamber.segments) {
904 matchedSegment.
x = segment.segmentLocalPosition.x();
905 matchedSegment.
y = segment.segmentLocalPosition.y();
906 matchedSegment.
dXdZ =
907 segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.x() / segment.segmentLocalDirection.z() : 0;
908 matchedSegment.
dYdZ =
909 segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.y() / segment.segmentLocalDirection.z() : 0;
910 matchedSegment.
xErr = segment.segmentLocalErrorXX > 0 ?
sqrt(segment.segmentLocalErrorXX) : 0;
911 matchedSegment.
yErr = segment.segmentLocalErrorYY > 0 ?
sqrt(segment.segmentLocalErrorYY) : 0;
912 matchedSegment.
dXdZErr = segment.segmentLocalErrorDxDz > 0 ?
sqrt(segment.segmentLocalErrorDxDz) : 0;
913 matchedSegment.
dYdZErr = segment.segmentLocalErrorDyDz > 0 ?
sqrt(segment.segmentLocalErrorDyDz) : 0;
914 matchedSegment.
t0 = segment.t0;
915 matchedSegment.
mask = 0;
920 matchedSegment.
hasZed_ = segment.hasZed;
921 matchedSegment.
hasPhi_ = segment.hasPhi;
923 bool matchedX =
false;
924 bool matchedY =
false;
925 LogTrace(
"MuonIdentification") <<
" matching local x, segment x: " << matchedSegment.
x
926 <<
", chamber x: " << matchedChamber.
x <<
", max: " <<
maxAbsDx_;
927 LogTrace(
"MuonIdentification") <<
" matching local y, segment y: " << matchedSegment.
y
928 <<
", chamber y: " << matchedChamber.
y <<
", max: " <<
maxAbsDy_;
929 const double matchedSegChDx =
std::abs(matchedSegment.
x - matchedChamber.
x);
930 const double matchedSegChDy =
std::abs(matchedSegment.
y - matchedChamber.
y);
931 const double matchedSegChPullX = matchedSegChDx / std::hypot(matchedSegment.
xErr, matchedChamber.
xErr);
932 const double matchedSegChPullY = matchedSegChDy / std::hypot(matchedSegment.
yErr, matchedChamber.
yErr);
933 if (matchedSegment.
xErr > 0 && matchedChamber.
xErr > 0)
934 LogTrace(
"MuonIdentification") <<
" xpull: " << matchedSegChPullX;
935 if (matchedSegment.
yErr > 0 && matchedChamber.
yErr > 0)
936 LogTrace(
"MuonIdentification") <<
" ypull: " << matchedSegChPullY;
946 if (matchedX && matchedY) {
948 matchedChamber.
me0Matches.push_back(matchedSegment);
950 matchedChamber.
gemMatches.push_back(matchedSegment);
955 muonChamberMatches.push_back(matchedChamber);
959 LogTrace(
"MuonIdentification") <<
"RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
962 if (
chamber.id.subdetId() != 3)
964 const auto& lErr =
chamber.tState.localError();
965 const auto& lPos =
chamber.tState.localPosition();
966 const auto& lDir =
chamber.tState.localDirection();
971 matchedChamber.
x = lPos.x();
972 matchedChamber.
y = lPos.y();
976 matchedChamber.
dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
977 matchedChamber.
dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
980 matchedChamber.
dXdZErr = trajectoryCovMatrix(1, 1) > 0 ?
sqrt(trajectoryCovMatrix(1, 1)) : 0;
981 matchedChamber.
dYdZErr = trajectoryCovMatrix(2, 2) > 0 ?
sqrt(trajectoryCovMatrix(2, 2)) : 0;
993 if (rpcRecHit.rawId() !=
chamber.id.rawId())
996 rpcHitMatch.
x = rpcRecHit.localPosition().x();
997 rpcHitMatch.
mask = 0;
998 rpcHitMatch.
bx = rpcRecHit.BunchX();
1000 const double absDx =
std::abs(rpcRecHit.localPosition().x() -
chamber.tState.localPosition().x());
1001 if (absDx <= 20
or absDx /
sqrt(localError.
xx()) <= 4)
1002 matchedChamber.
rpcMatches.push_back(rpcHitMatch);
1005 muonChamberMatches.push_back(matchedChamber);
1011 LogTrace(
"MuonIdentification") <<
"number of muon chambers: " << aMuon.
matches().size() <<
"\n"
1012 <<
"number of chambers with segments according to the associator requirements: "
1013 << nubmerOfMatchesAccordingToTrackAssociator;
1014 LogTrace(
"MuonIdentification") <<
"number of segment matches with the producer requirements: "
1025 if (
muon->isTrackerMuon()) {
1031 if ((
muon->type() & (~mask)) == 0) {
1038 muon->setType(
muon->type() & (~
reco::Muon::TrackerMuon));
1050 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > chamberPairs;
1051 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > stationPairs;
1052 std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> >
1056 for (
unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1) {
1057 auto& muon1 = pOutputMuons->at(muonIndex1);
1059 for (
auto& chamber1 : muon1.matches()) {
1061 std::vector<reco::MuonSegmentMatch>* segmentMatches1 =
getSegmentMatches(chamber1, muonType);
1063 if (segmentMatches1->empty())
1065 chamberPairs.clear();
1067 for (
auto& segment1 : *segmentMatches1) {
1068 chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1069 if (!segment1.isMask())
1071 arbitrationPairs.clear();
1072 arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1076 if (muon1.type() & muonType) {
1078 for (
unsigned int muonIndex2 = muonIndex1 + 1; muonIndex2 < pOutputMuons->size(); ++muonIndex2) {
1079 auto& muon2 = pOutputMuons->at(muonIndex2);
1081 if (!(muon2.type() & muonType))
1084 for (
auto& chamber2 : muon2.matches()) {
1086 std::vector<reco::MuonSegmentMatch>* segmentMatches2 =
getSegmentMatches(chamber2, muonType);
1087 for (
auto& segment2 : *segmentMatches2) {
1088 if (segment2.isMask())
1093 approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1094 approxEqual(segment2.dYdZErr, segment1.dYdZErr)) {
1095 arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1103 if (arbitrationPairs.empty())
1105 if (arbitrationPairs.size() == 1) {
1112 sort(arbitrationPairs.begin(),
1113 arbitrationPairs.end(),
1116 sort(arbitrationPairs.begin(),
1117 arbitrationPairs.end(),
1120 sort(arbitrationPairs.begin(),
1121 arbitrationPairs.end(),
1124 sort(arbitrationPairs.begin(),
1125 arbitrationPairs.end(),
1128 for (
auto& ap : arbitrationPairs) {
1137 for (
auto& segment2 : chamber1.segmentMatches) {
1138 if (segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull())
1140 if (
meshAlgo_->isDuplicateOf(segment1.cscSegmentRef, segment2.cscSegmentRef) &&
1141 (segment2.mask & 0x1e0000) && (segment1.mask & 0x1e0000)) {
1151 if (chamberPairs.empty())
1153 if (chamberPairs.size() == 1) {
1159 sort(chamberPairs.begin(),
1163 sort(chamberPairs.begin(),
1167 sort(chamberPairs.begin(),
1171 sort(chamberPairs.begin(),
1180 for (
int detectorIndex = 1; detectorIndex <= 5;
1183 stationPairs.clear();
1186 for (
auto&
chamber : muon1.matches()) {
1190 if (segmentMatches->empty())
1193 for (
auto& segment : *segmentMatches) {
1194 stationPairs.push_back(std::make_pair(&
chamber, &segment));
1198 if (stationPairs.empty())
1200 if (stationPairs.size() == 1) {
1206 sort(stationPairs.begin(),
1210 sort(stationPairs.begin(),
1214 sort(stationPairs.begin(),
1218 sort(stationPairs.begin(),
1250 <<
"Failed to compute muon isolation information for a muon with undefined references to tracks";
1259 if (caloDeps.size() != 3) {
1260 LogTrace(
"MuonIdentification") <<
"Failed to fill vector of calorimeter isolation deposits!";
1303 const double energy = hypot(
track.p(), 0.105658369);
1312 if (muonId.
sector() <= 12)
1314 if (muonId.
sector() == 13)
1316 if (muonId.
sector() == 14)
1329 if (
muon.isStandAloneMuon())
1330 return muon.standAloneMuon()->innerPosition().phi();
1332 if (
muon.matches().empty()) {
1333 if (
muon.innerTrack().isAvailable() &&
muon.innerTrack()->extra().isAvailable())
1334 return muon.innerTrack()->outerPosition().phi();
1363 const bool trackBAD =
links->trackerTrack().isNull();
1364 const bool staBAD =
links->standAloneTrack().isNull();
1365 const bool glbBAD =
links->globalTrack().isNull();
1366 if (trackBAD || staBAD || glbBAD) {
1367 edm::LogWarning(
"muonIDbadLinks") <<
"Global muon links to constituent tracks are invalid: trkBad " << trackBAD
1368 <<
" standaloneBad " << staBAD <<
" globalBad " << glbBAD
1369 <<
". There should be no such object. Muon is skipped.";
1379 desc.
add<
bool>(
"arbitrateTrackerMuons",
false);
1380 desc.
add<
bool>(
"storeCrossedHcalRecHits",
false);
1381 desc.
add<
bool>(
"fillShowerDigis",
false);
1386 descTrkAsoPar.add<
bool>(
"useGEM",
false);
1387 descTrkAsoPar.add<
bool>(
"useME0",
false);
1388 descTrkAsoPar.setAllowAnything();