Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-23 02:46:06

0001 #include "DataFormats/MuonReco/interface/Muon.h"
0002 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0003 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
0004 #include "DataFormats/MuonDetId/interface/GEMDetId.h"
0005 #include "DataFormats/MuonDetId/interface/ME0DetId.h"
0006 
0007 using namespace reco;
0008 
0009 Muon::Muon(Charge q, const LorentzVector& p4, const Point& vtx) : RecoCandidate(q, p4, vtx, -13 * q) {
0010   energyValid_ = false;
0011   matchesValid_ = false;
0012   isolationValid_ = false;
0013   pfIsolationValid_ = false;
0014   qualityValid_ = false;
0015   caloCompatibility_ = -9999.;
0016   type_ = 0;
0017   bestTunePTrackType_ = reco::Muon::None;
0018   bestTrackType_ = reco::Muon::None;
0019   selectors_ = 0;
0020 }
0021 
0022 Muon::Muon() {
0023   energyValid_ = false;
0024   matchesValid_ = false;
0025   isolationValid_ = false;
0026   pfIsolationValid_ = false;
0027   qualityValid_ = false;
0028   caloCompatibility_ = -9999.;
0029   type_ = 0;
0030   bestTrackType_ = reco::Muon::None;
0031   bestTunePTrackType_ = reco::Muon::None;
0032   selectors_ = 0;
0033 }
0034 
0035 bool Muon::overlap(const Candidate& c) const {
0036   const RecoCandidate* o = dynamic_cast<const RecoCandidate*>(&c);
0037   return (o != nullptr && (checkOverlap(track(), o->track()) || checkOverlap(standAloneMuon(), o->standAloneMuon()) ||
0038                            checkOverlap(combinedMuon(), o->combinedMuon()) ||
0039                            checkOverlap(standAloneMuon(), o->track()) || checkOverlap(combinedMuon(), o->track())));
0040 }
0041 
0042 Muon* Muon::clone() const { return new Muon(*this); }
0043 
0044 int Muon::numberOfChambersCSCorDT() const {
0045   int total = 0;
0046   int nAll = numberOfChambers();
0047   for (int iC = 0; iC < nAll; ++iC) {
0048     if (matches()[iC].detector() == MuonSubdetId::CSC || matches()[iC].detector() == MuonSubdetId::DT)
0049       total++;
0050   }
0051 
0052   return total;
0053 }
0054 
0055 int Muon::numberOfMatches(ArbitrationType type) const {
0056   int matches(0);
0057   for (auto& chamberMatch : muMatches_) {
0058     if (type == RPCHitAndTrackArbitration) {
0059       if (chamberMatch.rpcMatches.empty())
0060         continue;
0061       matches += chamberMatch.rpcMatches.size();
0062       continue;
0063     }
0064     if (type == ME0SegmentAndTrackArbitration) {
0065       if (chamberMatch.me0Matches.empty())
0066         continue;
0067       matches += chamberMatch.me0Matches.size();
0068       continue;
0069     }
0070     if (type == GEMSegmentAndTrackArbitration) {
0071       if (chamberMatch.gemMatches.empty())
0072         continue;
0073       matches += chamberMatch.gemMatches.size();
0074       continue;
0075     }
0076 
0077     if (type == GEMHitAndTrackArbitration) {
0078       if (chamberMatch.gemHitMatches.empty())
0079         continue;
0080       matches += chamberMatch.gemHitMatches.size();
0081       continue;
0082     }
0083 
0084     if (chamberMatch.segmentMatches.empty())
0085       continue;
0086     if (type == NoArbitration) {
0087       matches++;
0088       continue;
0089     }
0090 
0091     for (auto& segmentMatch : chamberMatch.segmentMatches) {
0092       if (type == SegmentArbitration)
0093         if (segmentMatch.isMask(MuonSegmentMatch::BestInChamberByDR)) {
0094           matches++;
0095           break;
0096         }
0097       if (type == SegmentAndTrackArbitration)
0098         if (segmentMatch.isMask(MuonSegmentMatch::BestInChamberByDR) &&
0099             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR)) {
0100           matches++;
0101           break;
0102         }
0103       if (type == SegmentAndTrackArbitrationCleaned)
0104         if (segmentMatch.isMask(MuonSegmentMatch::BestInChamberByDR) &&
0105             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR) &&
0106             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByCleaning)) {
0107           matches++;
0108           break;
0109         }
0110     }
0111   }
0112 
0113   return matches;
0114 }
0115 
0116 int Muon::numberOfMatchedStations(ArbitrationType type) const {
0117   int stations(0);
0118 
0119   unsigned int theStationMask = stationMask(type);
0120   // eight stations, eight bits
0121   for (int it = 0; it < 8; ++it)
0122     if (theStationMask & 1 << it)
0123       ++stations;
0124 
0125   return stations;
0126 }
0127 
0128 unsigned int Muon::expectedNnumberOfMatchedStations(float minDistanceFromEdge) const {
0129   unsigned int stationMask = 0;
0130   minDistanceFromEdge = std::abs(minDistanceFromEdge);
0131   for (auto& chamberMatch : muMatches_) {
0132     if (chamberMatch.detector() != MuonSubdetId::DT && chamberMatch.detector() != MuonSubdetId::CSC)
0133       continue;
0134     float edgeX = chamberMatch.edgeX;
0135     float edgeY = chamberMatch.edgeY;
0136     // check we if the trajectory is well within the acceptance
0137     if (edgeX < 0 && -edgeX > minDistanceFromEdge && edgeY < 0 && -edgeY > minDistanceFromEdge)
0138       stationMask |= 1 << ((chamberMatch.station() - 1) + 4 * (chamberMatch.detector() - 1));
0139   }
0140   unsigned int n = 0;
0141   for (unsigned int i = 0; i < 8; ++i)
0142     if (stationMask & (1 << i))
0143       n++;
0144   return n;
0145 }
0146 
0147 unsigned int Muon::stationMask(ArbitrationType type) const {
0148   unsigned int totMask(0);
0149   unsigned int curMask(0);
0150 
0151   for (auto& chamberMatch : muMatches_) {
0152     if (type == RPCHitAndTrackArbitration) {
0153       if (chamberMatch.rpcMatches.empty())
0154         continue;
0155       RPCDetId rollId = chamberMatch.id.rawId();
0156       int rpcIndex = rollId.region() == 0 ? 1 : 2;
0157       curMask = 1 << ((chamberMatch.station() - 1) + 4 * (rpcIndex - 1));
0158       // do not double count
0159       if (!(totMask & curMask))
0160         totMask += curMask;
0161       continue;
0162     }
0163 
0164     if (chamberMatch.segmentMatches.empty())
0165       continue;
0166     if (type == NoArbitration) {
0167       curMask = 1 << ((chamberMatch.station() - 1) + 4 * (chamberMatch.detector() - 1));
0168       // do not double count
0169       if (!(totMask & curMask))
0170         totMask += curMask;
0171       continue;
0172     }
0173 
0174     for (auto& segmentMatch : chamberMatch.segmentMatches) {
0175       if (type == SegmentArbitration)
0176         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR)) {
0177           curMask = 1 << ((chamberMatch.station() - 1) + 4 * (chamberMatch.detector() - 1));
0178           // do not double count
0179           if (!(totMask & curMask))
0180             totMask += curMask;
0181           break;
0182         }
0183       if (type == SegmentAndTrackArbitration)
0184         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR) &&
0185             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR)) {
0186           curMask = 1 << ((chamberMatch.station() - 1) + 4 * (chamberMatch.detector() - 1));
0187           // do not double count
0188           if (!(totMask & curMask))
0189             totMask += curMask;
0190           break;
0191         }
0192       if (type == SegmentAndTrackArbitrationCleaned)
0193         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR) &&
0194             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR) &&
0195             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByCleaning)) {
0196           curMask = 1 << ((chamberMatch.station() - 1) + 4 * (chamberMatch.detector() - 1));
0197           // do not double count
0198           if (!(totMask & curMask))
0199             totMask += curMask;
0200           break;
0201         }
0202     }
0203   }
0204 
0205   return totMask;
0206 }
0207 
0208 int Muon::numberOfMatchedRPCLayers(ArbitrationType type) const {
0209   int layers(0);
0210 
0211   unsigned int theRPCLayerMask = RPClayerMask(type);
0212   // maximum ten layers because of 6 layers in barrel and 3 (4) layers in each endcap before (after) upscope
0213   for (int it = 0; it < 10; ++it)
0214     if (theRPCLayerMask & 1 << it)
0215       ++layers;
0216 
0217   return layers;
0218 }
0219 
0220 unsigned int Muon::RPClayerMask(ArbitrationType type) const {
0221   unsigned int totMask(0);
0222   unsigned int curMask(0);
0223   for (auto& chamberMatch : muMatches_) {
0224     if (chamberMatch.rpcMatches.empty())
0225       continue;
0226 
0227     RPCDetId rollId = chamberMatch.id.rawId();
0228     const int region = rollId.region();
0229     const int stationIndex = chamberMatch.station();
0230     int rpcLayer = stationIndex;
0231     if (region == 0) {
0232       const int layer = rollId.layer();
0233       rpcLayer = stationIndex - 1 + stationIndex * layer;
0234       if ((stationIndex == 2 && layer == 2) || (stationIndex == 4 && layer == 1))
0235         rpcLayer -= 1;
0236     } else
0237       rpcLayer += 6;
0238 
0239     curMask = 1 << (rpcLayer - 1);
0240     // do not double count
0241     if (!(totMask & curMask))
0242       totMask += curMask;
0243   }
0244 
0245   return totMask;
0246 }
0247 
0248 unsigned int Muon::stationGapMaskDistance(float distanceCut) const {
0249   unsigned int totMask(0);
0250   distanceCut = std::abs(distanceCut);
0251   for (auto& chamberMatch : muMatches_) {
0252     unsigned int curMask(0);
0253     const int detectorIndex = chamberMatch.detector();
0254     if (detectorIndex < 1 || detectorIndex >= 4)
0255       continue;
0256     const int stationIndex = chamberMatch.station();
0257     if (stationIndex < 1 || stationIndex >= 5)
0258       continue;
0259 
0260     float edgeX = chamberMatch.edgeX;
0261     float edgeY = chamberMatch.edgeY;
0262     if (edgeX < 0 && -edgeX > distanceCut && edgeY < 0 &&
0263         -edgeY > distanceCut)  // inside the chamber so negates all gaps for this station
0264       continue;
0265 
0266     if ((std::abs(edgeX) < distanceCut && edgeY < distanceCut) ||
0267         (std::abs(edgeY) < distanceCut && edgeX < distanceCut))  // inside gap
0268       curMask = 1 << ((stationIndex - 1) + 4 * (detectorIndex - 1));
0269     totMask += curMask;  // add to total mask
0270   }
0271 
0272   return totMask;
0273 }
0274 
0275 unsigned int Muon::stationGapMaskPull(float sigmaCut) const {
0276   sigmaCut = std::abs(sigmaCut);
0277   unsigned int totMask(0);
0278   for (auto& chamberMatch : muMatches_) {
0279     unsigned int curMask(0);
0280     const int detectorIndex = chamberMatch.detector();
0281     if (detectorIndex < 1 || detectorIndex >= 4)
0282       continue;
0283     const int stationIndex = chamberMatch.station();
0284     if (stationIndex < 1 || stationIndex >= 5)
0285       continue;
0286 
0287     float edgeX = chamberMatch.edgeX;
0288     float edgeY = chamberMatch.edgeY;
0289     float xErr = chamberMatch.xErr + 0.000001;  // protect against division by zero later
0290     float yErr = chamberMatch.yErr + 0.000001;  // protect against division by zero later
0291     if (edgeX < 0 && std::abs(edgeX / xErr) > sigmaCut && edgeY < 0 &&
0292         std::abs(edgeY / yErr) > sigmaCut)  // inside the chamber so negates all gaps for this station
0293       continue;
0294 
0295     if ((std::abs(edgeX / xErr) < sigmaCut && edgeY < sigmaCut * yErr) ||
0296         (std::abs(edgeY / yErr) < sigmaCut && edgeX < sigmaCut * xErr))  // inside gap
0297       curMask = 1 << ((stationIndex - 1) + 4 * (detectorIndex - 1));
0298     totMask += curMask;  // add to total mask
0299   }
0300 
0301   return totMask;
0302 }
0303 
0304 int Muon::nDigisInStation(int station, int muonSubdetId) const {
0305   int nDigis(0);
0306   std::map<int, int> me11DigisPerCh;
0307 
0308   if (muonSubdetId != MuonSubdetId::CSC && muonSubdetId != MuonSubdetId::DT)
0309     return 0;
0310 
0311   for (auto& match : muMatches_) {
0312     if (match.detector() != muonSubdetId || match.station() != station)
0313       continue;
0314 
0315     int nDigisInCh = match.nDigisInRange;
0316 
0317     if (muonSubdetId == MuonSubdetId::CSC && station == 1) {
0318       CSCDetId id(match.id.rawId());
0319 
0320       int chamber = id.chamber();
0321       int ring = id.ring();
0322 
0323       if (ring == 1 || ring == 4)  // merge ME1/1a and ME1/1b digis
0324       {
0325         if (me11DigisPerCh.find(chamber) == me11DigisPerCh.end())
0326           me11DigisPerCh[chamber] = 0;
0327 
0328         me11DigisPerCh[chamber] += nDigisInCh;
0329 
0330         continue;
0331       }
0332     }
0333 
0334     if (nDigisInCh > nDigis)
0335       nDigis = nDigisInCh;
0336   }
0337 
0338   for (const auto& me11DigisInCh : me11DigisPerCh) {
0339     int nMe11DigisInCh = me11DigisInCh.second;
0340     if (nMe11DigisInCh > nDigis)
0341       nDigis = nMe11DigisInCh;
0342   }
0343 
0344   return nDigis;
0345 }
0346 
0347 bool Muon::hasShowerInStation(int station, int muonSubdetId, int nDtDigisCut, int nCscDigisCut) const {
0348   if (muonSubdetId != MuonSubdetId::DT && muonSubdetId != MuonSubdetId::CSC)
0349     return false;
0350   auto nDigisCut = muonSubdetId == MuonSubdetId::DT ? nDtDigisCut : nCscDigisCut;
0351 
0352   return nDigisInStation(station, muonSubdetId) >= nDigisCut;
0353 }
0354 
0355 int Muon::numberOfShowers(int nDtDigisCut, int nCscDigisCut) const {
0356   int nShowers = 0;
0357   for (int station = 1; station < 5; ++station) {
0358     if (hasShowerInStation(station, MuonSubdetId::DT, nDtDigisCut, nCscDigisCut))
0359       nShowers++;
0360     if (hasShowerInStation(station, MuonSubdetId::CSC, nDtDigisCut, nCscDigisCut))
0361       nShowers++;
0362   }
0363 
0364   return nShowers;
0365 }
0366 
0367 int Muon::numberOfSegments(int station, int muonSubdetId, ArbitrationType type) const {
0368   int segments(0);
0369   for (auto& chamberMatch : muMatches_) {
0370     if (chamberMatch.segmentMatches.empty())
0371       continue;
0372     if (chamberMatch.detector() != muonSubdetId || chamberMatch.station() != station)
0373       continue;
0374 
0375     if (type == NoArbitration) {
0376       segments += chamberMatch.segmentMatches.size();
0377       continue;
0378     }
0379 
0380     for (auto& segmentMatch : chamberMatch.segmentMatches) {
0381       if (type == SegmentArbitration)
0382         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR)) {
0383           segments++;
0384           break;
0385         }
0386       if (type == SegmentAndTrackArbitration)
0387         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR) &&
0388             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR)) {
0389           segments++;
0390           break;
0391         }
0392       if (type == SegmentAndTrackArbitrationCleaned)
0393         if (segmentMatch.isMask(MuonSegmentMatch::BestInStationByDR) &&
0394             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByDR) &&
0395             segmentMatch.isMask(MuonSegmentMatch::BelongsToTrackByCleaning)) {
0396           segments++;
0397           break;
0398         }
0399     }
0400   }
0401 
0402   return segments;
0403 }
0404 
0405 const std::vector<const MuonChamberMatch*> Muon::chambers(int station, int muonSubdetId) const {
0406   std::vector<const MuonChamberMatch*> chambers;
0407   for (std::vector<MuonChamberMatch>::const_iterator chamberMatch = muMatches_.begin();
0408        chamberMatch != muMatches_.end();
0409        chamberMatch++)
0410     if (chamberMatch->detector() == muonSubdetId && chamberMatch->station() == station)
0411       chambers.push_back(&(*chamberMatch));
0412   return chambers;
0413 }
0414 
0415 std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> Muon::pair(
0416     const std::vector<const MuonChamberMatch*>& chambers, ArbitrationType type) const {
0417   MuonChamberMatch* m = nullptr;
0418   MuonSegmentMatch* s = nullptr;
0419   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair(m, s);
0420 
0421   if (chambers.empty())
0422     return chamberSegmentPair;
0423   for (std::vector<const MuonChamberMatch*>::const_iterator chamberMatch = chambers.begin();
0424        chamberMatch != chambers.end();
0425        chamberMatch++) {
0426     if ((*chamberMatch)->segmentMatches.empty())
0427       continue;
0428     if (type == NoArbitration)
0429       return std::make_pair(*chamberMatch, &((*chamberMatch)->segmentMatches.front()));
0430 
0431     for (std::vector<MuonSegmentMatch>::const_iterator segmentMatch = (*chamberMatch)->segmentMatches.begin();
0432          segmentMatch != (*chamberMatch)->segmentMatches.end();
0433          segmentMatch++) {
0434       if (type == SegmentArbitration)
0435         if (segmentMatch->isMask(MuonSegmentMatch::BestInStationByDR))
0436           return std::make_pair(*chamberMatch, &(*segmentMatch));
0437       if (type == SegmentAndTrackArbitration)
0438         if (segmentMatch->isMask(MuonSegmentMatch::BestInStationByDR) &&
0439             segmentMatch->isMask(MuonSegmentMatch::BelongsToTrackByDR))
0440           return std::make_pair(*chamberMatch, &(*segmentMatch));
0441       if (type == SegmentAndTrackArbitrationCleaned)
0442         if (segmentMatch->isMask(MuonSegmentMatch::BestInStationByDR) &&
0443             segmentMatch->isMask(MuonSegmentMatch::BelongsToTrackByDR) &&
0444             segmentMatch->isMask(MuonSegmentMatch::BelongsToTrackByCleaning))
0445           return std::make_pair(*chamberMatch, &(*segmentMatch));
0446     }
0447   }
0448 
0449   return chamberSegmentPair;
0450 }
0451 
0452 float Muon::dX(int station, int muonSubdetId, ArbitrationType type) const {
0453   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0454       pair(chambers(station, muonSubdetId), type);
0455   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0456     return 999999;
0457   if (!chamberSegmentPair.second->hasPhi())
0458     return 999999;
0459   return chamberSegmentPair.first->x - chamberSegmentPair.second->x;
0460 }
0461 
0462 float Muon::dY(int station, int muonSubdetId, ArbitrationType type) const {
0463   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0464     return 999999;  // no y information
0465   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0466       pair(chambers(station, muonSubdetId), type);
0467   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0468     return 999999;
0469   if (!chamberSegmentPair.second->hasZed())
0470     return 999999;
0471   return chamberSegmentPair.first->y - chamberSegmentPair.second->y;
0472 }
0473 
0474 float Muon::dDxDz(int station, int muonSubdetId, ArbitrationType type) const {
0475   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0476       pair(chambers(station, muonSubdetId), type);
0477   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0478     return 999999;
0479   if (!chamberSegmentPair.second->hasPhi())
0480     return 999999;
0481   return chamberSegmentPair.first->dXdZ - chamberSegmentPair.second->dXdZ;
0482 }
0483 
0484 float Muon::dDyDz(int station, int muonSubdetId, ArbitrationType type) const {
0485   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0486     return 999999;  // no y information
0487   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0488       pair(chambers(station, muonSubdetId), type);
0489   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0490     return 999999;
0491   if (!chamberSegmentPair.second->hasZed())
0492     return 999999;
0493   return chamberSegmentPair.first->dYdZ - chamberSegmentPair.second->dYdZ;
0494 }
0495 
0496 float Muon::pullX(int station, int muonSubdetId, ArbitrationType type, bool includeSegmentError) const {
0497   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0498       pair(chambers(station, muonSubdetId), type);
0499   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0500     return 999999;
0501   if (!chamberSegmentPair.second->hasPhi())
0502     return 999999;
0503   if (includeSegmentError)
0504     return (chamberSegmentPair.first->x - chamberSegmentPair.second->x) /
0505            sqrt(std::pow(chamberSegmentPair.first->xErr, 2) + std::pow(chamberSegmentPair.second->xErr, 2));
0506   return (chamberSegmentPair.first->x - chamberSegmentPair.second->x) / chamberSegmentPair.first->xErr;
0507 }
0508 
0509 float Muon::pullY(int station, int muonSubdetId, ArbitrationType type, bool includeSegmentError) const {
0510   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0511     return 999999;  // no y information
0512   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0513       pair(chambers(station, muonSubdetId), type);
0514   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0515     return 999999;
0516   if (!chamberSegmentPair.second->hasZed())
0517     return 999999;
0518   if (includeSegmentError)
0519     return (chamberSegmentPair.first->y - chamberSegmentPair.second->y) /
0520            sqrt(std::pow(chamberSegmentPair.first->yErr, 2) + std::pow(chamberSegmentPair.second->yErr, 2));
0521   return (chamberSegmentPair.first->y - chamberSegmentPair.second->y) / chamberSegmentPair.first->yErr;
0522 }
0523 
0524 float Muon::pullDxDz(int station, int muonSubdetId, ArbitrationType type, bool includeSegmentError) const {
0525   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0526       pair(chambers(station, muonSubdetId), type);
0527   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0528     return 999999;
0529   if (!chamberSegmentPair.second->hasPhi())
0530     return 999999;
0531   if (includeSegmentError)
0532     return (chamberSegmentPair.first->dXdZ - chamberSegmentPair.second->dXdZ) /
0533            sqrt(std::pow(chamberSegmentPair.first->dXdZErr, 2) + std::pow(chamberSegmentPair.second->dXdZErr, 2));
0534   return (chamberSegmentPair.first->dXdZ - chamberSegmentPair.second->dXdZ) / chamberSegmentPair.first->dXdZErr;
0535 }
0536 
0537 float Muon::pullDyDz(int station, int muonSubdetId, ArbitrationType type, bool includeSegmentError) const {
0538   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0539     return 999999;  // no y information
0540   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0541       pair(chambers(station, muonSubdetId), type);
0542   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0543     return 999999;
0544   if (!chamberSegmentPair.second->hasZed())
0545     return 999999;
0546   if (includeSegmentError)
0547     return (chamberSegmentPair.first->dYdZ - chamberSegmentPair.second->dYdZ) /
0548            sqrt(std::pow(chamberSegmentPair.first->dYdZErr, 2) + std::pow(chamberSegmentPair.second->dYdZErr, 2));
0549   return (chamberSegmentPair.first->dYdZ - chamberSegmentPair.second->dYdZ) / chamberSegmentPair.first->dYdZErr;
0550 }
0551 
0552 float Muon::segmentX(int station, int muonSubdetId, ArbitrationType type) const {
0553   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0554       pair(chambers(station, muonSubdetId), type);
0555   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0556     return 999999;
0557   if (!chamberSegmentPair.second->hasPhi())
0558     return 999999;
0559   return chamberSegmentPair.second->x;
0560 }
0561 
0562 float Muon::segmentY(int station, int muonSubdetId, ArbitrationType type) const {
0563   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0564     return 999999;  // no y information
0565   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0566       pair(chambers(station, muonSubdetId), type);
0567   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0568     return 999999;
0569   if (!chamberSegmentPair.second->hasZed())
0570     return 999999;
0571   return chamberSegmentPair.second->y;
0572 }
0573 
0574 float Muon::segmentDxDz(int station, int muonSubdetId, ArbitrationType type) const {
0575   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0576       pair(chambers(station, muonSubdetId), type);
0577   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0578     return 999999;
0579   if (!chamberSegmentPair.second->hasPhi())
0580     return 999999;
0581   return chamberSegmentPair.second->dXdZ;
0582 }
0583 
0584 float Muon::segmentDyDz(int station, int muonSubdetId, ArbitrationType type) const {
0585   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0586     return 999999;  // no y information
0587   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0588       pair(chambers(station, muonSubdetId), type);
0589   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0590     return 999999;
0591   if (!chamberSegmentPair.second->hasZed())
0592     return 999999;
0593   return chamberSegmentPair.second->dYdZ;
0594 }
0595 
0596 float Muon::segmentXErr(int station, int muonSubdetId, ArbitrationType type) const {
0597   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0598       pair(chambers(station, muonSubdetId), type);
0599   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0600     return 999999;
0601   if (!chamberSegmentPair.second->hasPhi())
0602     return 999999;
0603   return chamberSegmentPair.second->xErr;
0604 }
0605 
0606 float Muon::segmentYErr(int station, int muonSubdetId, ArbitrationType type) const {
0607   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0608     return 999999;  // no y information
0609   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0610       pair(chambers(station, muonSubdetId), type);
0611   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0612     return 999999;
0613   if (!chamberSegmentPair.second->hasZed())
0614     return 999999;
0615   return chamberSegmentPair.second->yErr;
0616 }
0617 
0618 float Muon::segmentDxDzErr(int station, int muonSubdetId, ArbitrationType type) const {
0619   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0620       pair(chambers(station, muonSubdetId), type);
0621   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0622     return 999999;
0623   if (!chamberSegmentPair.second->hasPhi())
0624     return 999999;
0625   return chamberSegmentPair.second->dXdZErr;
0626 }
0627 
0628 float Muon::segmentDyDzErr(int station, int muonSubdetId, ArbitrationType type) const {
0629   if (station == 4 && muonSubdetId == MuonSubdetId::DT)
0630     return 999999;  // no y information
0631   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair =
0632       pair(chambers(station, muonSubdetId), type);
0633   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr)
0634     return 999999;
0635   if (!chamberSegmentPair.second->hasZed())
0636     return 999999;
0637   return chamberSegmentPair.second->dYdZErr;
0638 }
0639 
0640 float Muon::trackEdgeX(int station, int muonSubdetId, ArbitrationType type) const {
0641   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0642   if (muonChambers.empty())
0643     return 999999;
0644 
0645   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0646   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0647     float dist = 999999;
0648     float supVar = 999999;
0649     for (const MuonChamberMatch* muonChamber : muonChambers) {
0650       float currDist = muonChamber->dist();
0651       if (currDist < dist) {
0652         dist = currDist;
0653         supVar = muonChamber->edgeX;
0654       }
0655     }
0656     return supVar;
0657   } else
0658     return chamberSegmentPair.first->edgeX;
0659 }
0660 
0661 float Muon::trackEdgeY(int station, int muonSubdetId, ArbitrationType type) const {
0662   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0663   if (muonChambers.empty())
0664     return 999999;
0665 
0666   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0667   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0668     float dist = 999999;
0669     float supVar = 999999;
0670     for (const MuonChamberMatch* muonChamber : muonChambers) {
0671       float currDist = muonChamber->dist();
0672       if (currDist < dist) {
0673         dist = currDist;
0674         supVar = muonChamber->edgeY;
0675       }
0676     }
0677     return supVar;
0678   } else
0679     return chamberSegmentPair.first->edgeY;
0680 }
0681 
0682 float Muon::trackX(int station, int muonSubdetId, ArbitrationType type) const {
0683   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0684   if (muonChambers.empty())
0685     return 999999;
0686 
0687   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0688   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0689     float dist = 999999;
0690     float supVar = 999999;
0691     for (const MuonChamberMatch* muonChamber : muonChambers) {
0692       float currDist = muonChamber->dist();
0693       if (currDist < dist) {
0694         dist = currDist;
0695         supVar = muonChamber->x;
0696       }
0697     }
0698     return supVar;
0699   } else
0700     return chamberSegmentPair.first->x;
0701 }
0702 
0703 float Muon::trackY(int station, int muonSubdetId, ArbitrationType type) const {
0704   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0705   if (muonChambers.empty())
0706     return 999999;
0707 
0708   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0709   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0710     float dist = 999999;
0711     float supVar = 999999;
0712     for (const MuonChamberMatch* muonChamber : muonChambers) {
0713       float currDist = muonChamber->dist();
0714       if (currDist < dist) {
0715         dist = currDist;
0716         supVar = muonChamber->y;
0717       }
0718     }
0719     return supVar;
0720   } else
0721     return chamberSegmentPair.first->y;
0722 }
0723 
0724 float Muon::trackDxDz(int station, int muonSubdetId, ArbitrationType type) const {
0725   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0726   if (muonChambers.empty())
0727     return 999999;
0728 
0729   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0730   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0731     float dist = 999999;
0732     float supVar = 999999;
0733     for (const MuonChamberMatch* muonChamber : muonChambers) {
0734       float currDist = muonChamber->dist();
0735       if (currDist < dist) {
0736         dist = currDist;
0737         supVar = muonChamber->dXdZ;
0738       }
0739     }
0740     return supVar;
0741   } else
0742     return chamberSegmentPair.first->dXdZ;
0743 }
0744 
0745 float Muon::trackDyDz(int station, int muonSubdetId, ArbitrationType type) const {
0746   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0747   if (muonChambers.empty())
0748     return 999999;
0749 
0750   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0751   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0752     float dist = 999999;
0753     float supVar = 999999;
0754     for (const MuonChamberMatch* muonChamber : muonChambers) {
0755       float currDist = muonChamber->dist();
0756       if (currDist < dist) {
0757         dist = currDist;
0758         supVar = muonChamber->dYdZ;
0759       }
0760     }
0761     return supVar;
0762   } else
0763     return chamberSegmentPair.first->dYdZ;
0764 }
0765 
0766 float Muon::trackXErr(int station, int muonSubdetId, ArbitrationType type) const {
0767   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0768   if (muonChambers.empty())
0769     return 999999;
0770 
0771   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0772   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0773     float dist = 999999;
0774     float supVar = 999999;
0775     for (const MuonChamberMatch* muonChamber : muonChambers) {
0776       float currDist = muonChamber->dist();
0777       if (currDist < dist) {
0778         dist = currDist;
0779         supVar = muonChamber->xErr;
0780       }
0781     }
0782     return supVar;
0783   } else
0784     return chamberSegmentPair.first->xErr;
0785 }
0786 
0787 float Muon::trackYErr(int station, int muonSubdetId, ArbitrationType type) const {
0788   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0789   if (muonChambers.empty())
0790     return 999999;
0791 
0792   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0793   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0794     float dist = 999999;
0795     float supVar = 999999;
0796     for (const MuonChamberMatch* muonChamber : muonChambers) {
0797       float currDist = muonChamber->dist();
0798       if (currDist < dist) {
0799         dist = currDist;
0800         supVar = muonChamber->yErr;
0801       }
0802     }
0803     return supVar;
0804   } else
0805     return chamberSegmentPair.first->yErr;
0806 }
0807 
0808 float Muon::trackDxDzErr(int station, int muonSubdetId, ArbitrationType type) const {
0809   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0810   if (muonChambers.empty())
0811     return 999999;
0812 
0813   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0814   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0815     float dist = 999999;
0816     float supVar = 999999;
0817     for (const MuonChamberMatch* muonChamber : muonChambers) {
0818       float currDist = muonChamber->dist();
0819       if (currDist < dist) {
0820         dist = currDist;
0821         supVar = muonChamber->dXdZErr;
0822       }
0823     }
0824     return supVar;
0825   } else
0826     return chamberSegmentPair.first->dXdZErr;
0827 }
0828 
0829 float Muon::trackDyDzErr(int station, int muonSubdetId, ArbitrationType type) const {
0830   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0831   if (muonChambers.empty())
0832     return 999999;
0833 
0834   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0835   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0836     float dist = 999999;
0837     float supVar = 999999;
0838     for (const MuonChamberMatch* muonChamber : muonChambers) {
0839       float currDist = muonChamber->dist();
0840       if (currDist < dist) {
0841         dist = currDist;
0842         supVar = muonChamber->dYdZErr;
0843       }
0844     }
0845     return supVar;
0846   } else
0847     return chamberSegmentPair.first->dYdZErr;
0848 }
0849 
0850 float Muon::trackDist(int station, int muonSubdetId, ArbitrationType type) const {
0851   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0852   if (muonChambers.empty())
0853     return 999999;
0854 
0855   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0856   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0857     float dist = 999999;
0858     for (const MuonChamberMatch* muonChamber : muonChambers) {
0859       float currDist = muonChamber->dist();
0860       if (currDist < dist)
0861         dist = currDist;
0862     }
0863     return dist;
0864   } else
0865     return chamberSegmentPair.first->dist();
0866 }
0867 
0868 float Muon::trackDistErr(int station, int muonSubdetId, ArbitrationType type) const {
0869   const std::vector<const MuonChamberMatch*> muonChambers = chambers(station, muonSubdetId);
0870   if (muonChambers.empty())
0871     return 999999;
0872 
0873   std::pair<const MuonChamberMatch*, const MuonSegmentMatch*> chamberSegmentPair = pair(muonChambers, type);
0874   if (chamberSegmentPair.first == nullptr || chamberSegmentPair.second == nullptr) {
0875     float dist = 999999;
0876     float supVar = 999999;
0877     for (const MuonChamberMatch* muonChamber : muonChambers) {
0878       float currDist = muonChamber->dist();
0879       if (currDist < dist) {
0880         dist = currDist;
0881         supVar = muonChamber->distErr();
0882       }
0883     }
0884     return supVar;
0885   } else
0886     return chamberSegmentPair.first->distErr();
0887 }
0888 
0889 void Muon::setIsolation(const MuonIsolation& isoR03, const MuonIsolation& isoR05) {
0890   isolationR03_ = isoR03;
0891   isolationR05_ = isoR05;
0892   isolationValid_ = true;
0893 }
0894 
0895 void Muon::setPFIsolation(const std::string& label, const MuonPFIsolation& deposit) {
0896   if (label == "pfIsolationR03")
0897     pfIsolationR03_ = deposit;
0898 
0899   if (label == "pfIsolationR04")
0900     pfIsolationR04_ = deposit;
0901 
0902   if (label == "pfIsoMeanDRProfileR03")
0903     pfIsoMeanDRR03_ = deposit;
0904 
0905   if (label == "pfIsoMeanDRProfileR04")
0906     pfIsoMeanDRR04_ = deposit;
0907 
0908   if (label == "pfIsoSumDRProfileR03")
0909     pfIsoSumDRR03_ = deposit;
0910 
0911   if (label == "pfIsoSumDRProfileR04")
0912     pfIsoSumDRR04_ = deposit;
0913 
0914   pfIsolationValid_ = true;
0915 }
0916 
0917 void Muon::setPFP4(const reco::Candidate::LorentzVector& p4) {
0918   pfP4_ = p4;
0919   type_ = type_ | PFMuon;
0920 }
0921 
0922 void Muon::setOuterTrack(const TrackRef& t) { outerTrack_ = t; }
0923 void Muon::setInnerTrack(const TrackRef& t) { innerTrack_ = t; }
0924 void Muon::setTrack(const TrackRef& t) { setInnerTrack(t); }
0925 void Muon::setStandAlone(const TrackRef& t) { setOuterTrack(t); }
0926 void Muon::setGlobalTrack(const TrackRef& t) { globalTrack_ = t; }
0927 void Muon::setCombined(const TrackRef& t) { setGlobalTrack(t); }
0928 
0929 bool Muon::isAValidMuonTrack(const MuonTrackType& type) const { return muonTrack(type).isNonnull(); }
0930 
0931 TrackRef Muon::muonTrack(const MuonTrackType& type) const {
0932   switch (type) {
0933     case InnerTrack:
0934       return innerTrack();
0935     case OuterTrack:
0936       return standAloneMuon();
0937     case CombinedTrack:
0938       return globalTrack();
0939     case TPFMS:
0940       return tpfmsTrack();
0941     case Picky:
0942       return pickyTrack();
0943     case DYT:
0944       return dytTrack();
0945     default:
0946       return muonTrackFromMap(type);
0947   }
0948 }
0949 
0950 void Muon::setMuonTrack(const MuonTrackType& type, const TrackRef& t) {
0951   switch (type) {
0952     case InnerTrack:
0953       setInnerTrack(t);
0954       break;
0955     case OuterTrack:
0956       setStandAlone(t);
0957       break;
0958     case CombinedTrack:
0959       setGlobalTrack(t);
0960       break;
0961     default:
0962       refittedTrackMap_[type] = t;
0963       break;
0964   }
0965 }