Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:57

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