Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-16 06:12:37

0001 //
0002 //
0003 
0004 #include "DataFormats/PatCandidates/interface/Muon.h"
0005 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 #include "DataFormats/Common/interface/RefToPtr.h"
0008 #include <limits>
0009 
0010 using namespace pat;
0011 
0012 /// default constructor
0013 Muon::Muon()
0014     : Lepton<reco::Muon>(),
0015       embeddedMuonBestTrack_(false),
0016       embeddedTunePMuonBestTrack_(false),
0017       embeddedTrack_(false),
0018       embeddedStandAloneMuon_(false),
0019       embeddedCombinedMuon_(false),
0020       embeddedTCMETMuonCorrs_(false),
0021       embeddedCaloMETMuonCorrs_(false),
0022       embeddedPickyMuon_(false),
0023       embeddedTpfmsMuon_(false),
0024       embeddedDytMuon_(false),
0025       embeddedPFCandidate_(false),
0026       pfCandidateRef_(),
0027       cachedNormChi2_(false),
0028       normChi2_(0.0),
0029       cachedNumberOfValidHits_(false),
0030       numberOfValidHits_(0),
0031       pfEcalEnergy_(0),
0032       jetPtRatio_(0),
0033       jetPtRel_(0),
0034       mvaValue_(0),
0035       lowptMvaValue_(0),
0036       mvaIDValue_(0),
0037       softMvaValue_(0),
0038       inverseBeta_(0),
0039       inverseBetaErr_(0) {
0040   initImpactParameters();
0041   initSimInfo();
0042 }
0043 
0044 /// constructor from reco::Muon
0045 Muon::Muon(const reco::Muon& aMuon)
0046     : Lepton<reco::Muon>(aMuon),
0047       embeddedMuonBestTrack_(false),
0048       embeddedTunePMuonBestTrack_(false),
0049       embeddedTrack_(false),
0050       embeddedStandAloneMuon_(false),
0051       embeddedCombinedMuon_(false),
0052       embeddedTCMETMuonCorrs_(false),
0053       embeddedCaloMETMuonCorrs_(false),
0054       embeddedPickyMuon_(false),
0055       embeddedTpfmsMuon_(false),
0056       embeddedDytMuon_(false),
0057       embeddedPFCandidate_(false),
0058       pfCandidateRef_(),
0059       cachedNormChi2_(false),
0060       normChi2_(0.0),
0061       cachedNumberOfValidHits_(false),
0062       numberOfValidHits_(0),
0063       pfEcalEnergy_(0),
0064       jetPtRatio_(0),
0065       jetPtRel_(0),
0066       mvaValue_(0),
0067       lowptMvaValue_(0),
0068       mvaIDValue_(0),
0069       softMvaValue_(0),
0070       inverseBeta_(0),
0071       inverseBetaErr_(0) {
0072   initImpactParameters();
0073   initSimInfo();
0074 }
0075 
0076 /// constructor from ref to reco::Muon
0077 Muon::Muon(const edm::RefToBase<reco::Muon>& aMuonRef)
0078     : Lepton<reco::Muon>(aMuonRef),
0079       embeddedMuonBestTrack_(false),
0080       embeddedTunePMuonBestTrack_(false),
0081       embeddedTrack_(false),
0082       embeddedStandAloneMuon_(false),
0083       embeddedCombinedMuon_(false),
0084       embeddedTCMETMuonCorrs_(false),
0085       embeddedCaloMETMuonCorrs_(false),
0086       embeddedPickyMuon_(false),
0087       embeddedTpfmsMuon_(false),
0088       embeddedDytMuon_(false),
0089       embeddedPFCandidate_(false),
0090       pfCandidateRef_(),
0091       cachedNormChi2_(false),
0092       normChi2_(0.0),
0093       cachedNumberOfValidHits_(false),
0094       numberOfValidHits_(0),
0095       pfEcalEnergy_(0),
0096       jetPtRatio_(0),
0097       jetPtRel_(0),
0098       mvaValue_(0),
0099       lowptMvaValue_(0),
0100       mvaIDValue_(0),
0101       softMvaValue_(0),
0102       inverseBeta_(0),
0103       inverseBetaErr_(0) {
0104   initImpactParameters();
0105   initSimInfo();
0106 }
0107 
0108 /// constructor from ref to reco::Muon
0109 Muon::Muon(const edm::Ptr<reco::Muon>& aMuonRef)
0110     : Lepton<reco::Muon>(aMuonRef),
0111       embeddedMuonBestTrack_(false),
0112       embeddedTunePMuonBestTrack_(false),
0113       embeddedTrack_(false),
0114       embeddedStandAloneMuon_(false),
0115       embeddedCombinedMuon_(false),
0116       embeddedTCMETMuonCorrs_(false),
0117       embeddedCaloMETMuonCorrs_(false),
0118       embeddedPickyMuon_(false),
0119       embeddedTpfmsMuon_(false),
0120       embeddedDytMuon_(false),
0121       embeddedPFCandidate_(false),
0122       pfCandidateRef_(),
0123       cachedNormChi2_(false),
0124       normChi2_(0.0),
0125       cachedNumberOfValidHits_(false),
0126       numberOfValidHits_(0),
0127       pfEcalEnergy_(0),
0128       jetPtRatio_(0),
0129       jetPtRel_(0),
0130       mvaValue_(0),
0131       lowptMvaValue_(0),
0132       mvaIDValue_(0),
0133       softMvaValue_(0),
0134       inverseBeta_(0),
0135       inverseBetaErr_(0) {
0136   initImpactParameters();
0137   initSimInfo();
0138 }
0139 
0140 /// destructor
0141 Muon::~Muon() {}
0142 
0143 std::ostream& reco::operator<<(std::ostream& out, const pat::Muon& obj) {
0144   if (!out)
0145     return out;
0146 
0147   out << "\tpat::Muon: ";
0148   out << std::setiosflags(std::ios::right);
0149   out << std::setiosflags(std::ios::fixed);
0150   out << std::setprecision(3);
0151   out << " E/pT/eta/phi " << obj.energy() << "/" << obj.pt() << "/" << obj.eta() << "/" << obj.phi();
0152   return out;
0153 }
0154 
0155 // initialize impact parameter container vars
0156 void Muon::initImpactParameters() {
0157   std::fill(ip_, ip_ + IpTypeSize, 0.0f);
0158   std::fill(eip_, eip_ + IpTypeSize, 0.0f);
0159   cachedIP_ = 0;
0160 }
0161 
0162 // initialize impact parameter container vars
0163 void Muon::initSimInfo() {
0164   simType_ = reco::MuonSimType::Unknown;
0165   simExtType_ = reco::ExtendedMuonSimType::ExtUnknown;
0166   simFlavour_ = 0;
0167   simHeaviestMotherFlavour_ = 0;
0168   simPdgId_ = 0;
0169   simMotherPdgId_ = 0;
0170   simBX_ = 999;
0171   simTpEvent_ = 0;
0172   simProdRho_ = 0.0;
0173   simProdZ_ = 0.0;
0174   simPt_ = 0.0;
0175   simEta_ = 0.0;
0176   simPhi_ = 0.0;
0177   simMatchQuality_ = 0.0;
0178 }
0179 
0180 /// reference to Track reconstructed in the tracker only (reimplemented from reco::Muon)
0181 reco::TrackRef Muon::track() const {
0182   if (embeddedTrack_) {
0183     return reco::TrackRef(&track_, 0);
0184   } else {
0185     return reco::Muon::innerTrack();
0186   }
0187 }
0188 
0189 /// reference to Track reconstructed in the muon detector only (reimplemented from reco::Muon)
0190 reco::TrackRef Muon::standAloneMuon() const {
0191   if (embeddedStandAloneMuon_) {
0192     return reco::TrackRef(&standAloneMuon_, 0);
0193   } else {
0194     return reco::Muon::outerTrack();
0195   }
0196 }
0197 
0198 /// reference to Track reconstructed in both tracked and muon detector (reimplemented from reco::Muon)
0199 reco::TrackRef Muon::combinedMuon() const {
0200   if (embeddedCombinedMuon_) {
0201     return reco::TrackRef(&combinedMuon_, 0);
0202   } else {
0203     return reco::Muon::globalTrack();
0204   }
0205 }
0206 
0207 /// reference to Track reconstructed using hits in the tracker + "good" muon hits
0208 reco::TrackRef Muon::pickyTrack() const {
0209   if (embeddedPickyMuon_) {
0210     return reco::TrackRef(&pickyMuon_, 0);
0211   } else {
0212     return reco::Muon::pickyTrack();
0213   }
0214 }
0215 
0216 /// reference to Track reconstructed using hits in the tracker + info from the first muon station that has hits
0217 reco::TrackRef Muon::tpfmsTrack() const {
0218   if (embeddedTpfmsMuon_) {
0219     return reco::TrackRef(&tpfmsMuon_, 0);
0220   } else {
0221     return reco::Muon::tpfmsTrack();
0222   }
0223 }
0224 
0225 /// reference to Track reconstructed using hits in the tracker + info from the first muon station that has hits
0226 reco::TrackRef Muon::dytTrack() const {
0227   if (embeddedDytMuon_) {
0228     return reco::TrackRef(&dytMuon_, 0);
0229   } else {
0230     return reco::Muon::dytTrack();
0231   }
0232 }
0233 
0234 /// reference to Track giving best momentum (global PFlow algo)
0235 reco::TrackRef Muon::muonBestTrack() const {
0236   if (!muonBestTrack_.empty()) {
0237     return reco::TrackRef(&muonBestTrack_, 0);
0238   } else {
0239     return reco::Muon::muonBestTrack();
0240   }
0241 }
0242 
0243 /// reference to Track giving best momentum (muon only)
0244 reco::TrackRef Muon::tunePMuonBestTrack() const {
0245   if (!tunePMuonBestTrack_.empty()) {
0246     return reco::TrackRef(&tunePMuonBestTrack_, 0);
0247   } else if (muonBestTrackType() == tunePMuonBestTrackType()) {
0248     return muonBestTrack();
0249   } else {
0250     return reco::Muon::tunePMuonBestTrack();
0251   }
0252 }
0253 
0254 /// reference to the source IsolatedPFCandidates
0255 reco::PFCandidateRef Muon::pfCandidateRef() const {
0256   if (embeddedPFCandidate_) {
0257     return reco::PFCandidateRef(&pfCandidate_, 0);
0258   } else {
0259     return pfCandidateRef_;
0260   }
0261 }
0262 
0263 /// reference to the parent PF candidate for use in TopProjector
0264 reco::CandidatePtr Muon::sourceCandidatePtr(size_type i) const {
0265   if (pfCandidateRef_.isNonnull() && i == 0)
0266     return reco::CandidatePtr(edm::refToPtr(pfCandidateRef_));
0267   if (refToOrig_.isNonnull() && pfCandidateRef_.isNonnull() && i == 1)
0268     return refToOrig_;
0269   if (refToOrig_.isNonnull() && !pfCandidateRef_.isNonnull() && i == 0)
0270     return refToOrig_;
0271   return reco::CandidatePtr();
0272 }
0273 
0274 /// embed the Track selected to be the best measurement of the muon parameters
0275 void Muon::embedMuonBestTrack(bool force) {
0276   muonBestTrack_.clear();
0277   embeddedMuonBestTrack_ = false;
0278   bool alreadyEmbedded = false;
0279   if (!force) {
0280     switch (muonBestTrackType()) {
0281       case None:
0282         alreadyEmbedded = true;
0283         break;
0284       case InnerTrack:
0285         if (embeddedTrack_)
0286           alreadyEmbedded = true;
0287         break;
0288       case OuterTrack:
0289         if (embeddedStandAloneMuon_)
0290           alreadyEmbedded = true;
0291         break;
0292       case CombinedTrack:
0293         if (embeddedCombinedMuon_)
0294           alreadyEmbedded = true;
0295         break;
0296       case TPFMS:
0297         if (embeddedTpfmsMuon_)
0298           alreadyEmbedded = true;
0299         break;
0300       case Picky:
0301         if (embeddedPickyMuon_)
0302           alreadyEmbedded = true;
0303         break;
0304       case DYT:
0305         if (embeddedDytMuon_)
0306           alreadyEmbedded = true;
0307         break;
0308     }
0309   }
0310   if (force || !alreadyEmbedded) {
0311     muonBestTrack_.push_back(*reco::Muon::muonBestTrack());
0312     embeddedMuonBestTrack_ = true;
0313   }
0314 }
0315 
0316 /// embed the Track selected to be the best measurement of the muon parameters
0317 void Muon::embedTunePMuonBestTrack(bool force) {
0318   tunePMuonBestTrack_.clear();
0319   bool alreadyEmbedded = false;
0320   embeddedTunePMuonBestTrack_ = false;
0321   if (!force) {
0322     switch (tunePMuonBestTrackType()) {
0323       case None:
0324         alreadyEmbedded = true;
0325         break;
0326       case InnerTrack:
0327         if (embeddedTrack_)
0328           alreadyEmbedded = true;
0329         break;
0330       case OuterTrack:
0331         if (embeddedStandAloneMuon_)
0332           alreadyEmbedded = true;
0333         break;
0334       case CombinedTrack:
0335         if (embeddedCombinedMuon_)
0336           alreadyEmbedded = true;
0337         break;
0338       case TPFMS:
0339         if (embeddedTpfmsMuon_)
0340           alreadyEmbedded = true;
0341         break;
0342       case Picky:
0343         if (embeddedPickyMuon_)
0344           alreadyEmbedded = true;
0345         break;
0346       case DYT:
0347         if (embeddedDytMuon_)
0348           alreadyEmbedded = true;
0349         break;
0350     }
0351     if (muonBestTrackType() == tunePMuonBestTrackType()) {
0352       if (embeddedMuonBestTrack_)
0353         alreadyEmbedded = true;
0354     }
0355   }
0356   if (force || !alreadyEmbedded) {
0357     tunePMuonBestTrack_.push_back(*reco::Muon::tunePMuonBestTrack());
0358     embeddedTunePMuonBestTrack_ = true;
0359   }
0360 }
0361 
0362 /// embed the Track reconstructed in the tracker only
0363 void Muon::embedTrack() {
0364   track_.clear();
0365   if (reco::Muon::innerTrack().isNonnull()) {
0366     track_.push_back(*reco::Muon::innerTrack());
0367     embeddedTrack_ = true;
0368   }
0369 }
0370 
0371 /// embed the Track reconstructed in the muon detector only
0372 void Muon::embedStandAloneMuon() {
0373   standAloneMuon_.clear();
0374   if (reco::Muon::outerTrack().isNonnull()) {
0375     standAloneMuon_.push_back(*reco::Muon::outerTrack());
0376     embeddedStandAloneMuon_ = true;
0377   }
0378 }
0379 
0380 /// embed the Track reconstructed in both tracked and muon detector
0381 void Muon::embedCombinedMuon() {
0382   combinedMuon_.clear();
0383   if (reco::Muon::globalTrack().isNonnull()) {
0384     combinedMuon_.push_back(*reco::Muon::globalTrack());
0385     embeddedCombinedMuon_ = true;
0386   }
0387 }
0388 
0389 // recursively look for reassociated TrackExtraRefs in the edm::Associations and rekey
0390 void Muon::rekeyEmbeddedTracks(std::vector<edm::Handle<edm::Association<reco::TrackExtraCollection>>> const& assocs) {
0391   auto rekey = [&assocs](reco::Track& track) {
0392     reco::TrackExtraRef trackExtra = track.extra();
0393     for (auto const& assoc : assocs) {
0394       if (!assoc->contains(trackExtra.id())) {
0395         continue;
0396       }
0397       reco::TrackExtraRef const& trackExtraOut = (*assoc)[trackExtra];
0398       if (trackExtraOut.isNonnull()) {
0399         trackExtra = trackExtraOut;
0400       }
0401     }
0402     track.setExtra(trackExtra);
0403   };
0404 
0405   for (reco::Track& track : muonBestTrack_) {
0406     rekey(track);
0407   }
0408   for (reco::Track& track : tunePMuonBestTrack_) {
0409     rekey(track);
0410   }
0411   for (reco::Track& track : track_) {
0412     rekey(track);
0413   }
0414   for (reco::Track& track : standAloneMuon_) {
0415     rekey(track);
0416   }
0417   for (reco::Track& track : combinedMuon_) {
0418     rekey(track);
0419   }
0420   for (reco::Track& track : pickyMuon_) {
0421     rekey(track);
0422   }
0423   for (reco::Track& track : tpfmsMuon_) {
0424     rekey(track);
0425   }
0426   for (reco::Track& track : dytMuon_) {
0427     rekey(track);
0428   }
0429 }
0430 
0431 /// embed the MuonMETCorrectionData for muon corrected caloMET
0432 void Muon::embedCaloMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
0433   caloMETMuonCorrs_.clear();
0434   caloMETMuonCorrs_.push_back(t);
0435   embeddedCaloMETMuonCorrs_ = true;
0436 }
0437 
0438 /// embed the MuonMETCorrectionData for tcMET
0439 void Muon::embedTcMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
0440   tcMETMuonCorrs_.clear();
0441   tcMETMuonCorrs_.push_back(t);
0442   embeddedTCMETMuonCorrs_ = true;
0443 }
0444 
0445 /// embed the picky Track
0446 void Muon::embedPickyMuon() {
0447   pickyMuon_.clear();
0448   reco::TrackRef tk = reco::Muon::pickyTrack();
0449   if (tk.isNonnull()) {
0450     pickyMuon_.push_back(*tk);
0451     embeddedPickyMuon_ = true;
0452   }
0453 }
0454 
0455 /// embed the tpfms Track
0456 void Muon::embedTpfmsMuon() {
0457   tpfmsMuon_.clear();
0458   reco::TrackRef tk = reco::Muon::tpfmsTrack();
0459   if (tk.isNonnull()) {
0460     tpfmsMuon_.push_back(*tk);
0461     embeddedTpfmsMuon_ = true;
0462   }
0463 }
0464 
0465 /// embed the dyt Track
0466 void Muon::embedDytMuon() {
0467   dytMuon_.clear();
0468   reco::TrackRef tk = reco::Muon::dytTrack();
0469   if (tk.isNonnull()) {
0470     dytMuon_.push_back(*tk);
0471     embeddedDytMuon_ = true;
0472   }
0473 }
0474 
0475 /// Add extra timing information
0476 void Muon::readTimeExtra(const reco::MuonTimeExtra& t) {
0477   inverseBeta_ = t.inverseBeta();
0478   inverseBetaErr_ = t.inverseBetaErr();
0479 }
0480 
0481 /// embed the IsolatedPFCandidate pointed to by pfCandidateRef_
0482 void Muon::embedPFCandidate() {
0483   pfCandidate_.clear();
0484   if (pfCandidateRef_.isAvailable() && pfCandidateRef_.isNonnull()) {
0485     pfCandidate_.push_back(*pfCandidateRef_);
0486     embeddedPFCandidate_ = true;
0487   }
0488 }
0489 
0490 bool Muon::muonID(const std::string& name) const {
0491   muon::SelectionType st = muon::selectionTypeFromString(name);
0492   return muon::isGoodMuon(*this, st);
0493 }
0494 
0495 /// Norm chi2 gives the normalized chi2 of the global track.
0496 /// The user can choose to cache this info so they can drop the
0497 /// global track, or they can use the track itself if it is present
0498 /// in the event.
0499 double Muon::normChi2() const {
0500   if (cachedNormChi2_) {
0501     return normChi2_;
0502   } else {
0503     reco::TrackRef t = globalTrack();
0504     return t->chi2() / t->ndof();
0505   }
0506 }
0507 
0508 /// numberOfValidHits returns the number of valid hits on the global track.
0509 /// The user can choose to cache this info so they can drop the
0510 /// global track, or they can use the track itself if it is present
0511 /// in the event.
0512 unsigned int Muon::numberOfValidHits() const {
0513   if (cachedNumberOfValidHits_) {
0514     return numberOfValidHits_;
0515   } else {
0516     reco::TrackRef t = innerTrack();
0517     return t->numberOfValidHits();
0518   }
0519 }
0520 
0521 // embed various impact parameters with errors
0522 // IpType defines the type of the impact parameter
0523 double Muon::dB(IpType type_) const {
0524   // more IP types (new)
0525   if (cachedIP_ & (1 << int(type_))) {
0526     return ip_[type_];
0527   } else {
0528     return std::numeric_limits<double>::max();
0529   }
0530 }
0531 
0532 // embed various impact parameters with errors
0533 // IpType defines the type of the impact parameter
0534 double Muon::edB(IpType type_) const {
0535   // more IP types (new)
0536   if (cachedIP_ & (1 << int(type_))) {
0537     return eip_[type_];
0538   } else {
0539     return std::numeric_limits<double>::max();
0540   }
0541 }
0542 
0543 double Muon::segmentCompatibility(reco::Muon::ArbitrationType arbitrationType) const {
0544   return muon::segmentCompatibility(*this, arbitrationType);
0545 }
0546 
0547 // Selectors
0548 bool Muon::isTightMuon(const reco::Vertex& vtx) const { return muon::isTightMuon(*this, vtx); }
0549 
0550 bool Muon::isLooseMuon() const { return muon::isLooseMuon(*this); }
0551 
0552 bool Muon::isMediumMuon() const { return muon::isMediumMuon(*this); }
0553 
0554 bool Muon::isSoftMuon(const reco::Vertex& vtx) const { return muon::isSoftMuon(*this, vtx); }
0555 
0556 bool Muon::isHighPtMuon(const reco::Vertex& vtx) const { return muon::isHighPtMuon(*this, vtx); }