File indexing completed on 2023-03-28 01:34:05
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
0247 reco::PFCandidateRef Muon::pfCandidateRef() const {
0248 if (embeddedPFCandidate_) {
0249 return reco::PFCandidateRef(&pfCandidate_, 0);
0250 } else {
0251 return pfCandidateRef_;
0252 }
0253 }
0254
0255
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
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
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
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
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
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
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
0424 void Muon::embedCaloMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
0425 caloMETMuonCorrs_.clear();
0426 caloMETMuonCorrs_.push_back(t);
0427 embeddedCaloMETMuonCorrs_ = true;
0428 }
0429
0430
0431 void Muon::embedTcMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
0432 tcMETMuonCorrs_.clear();
0433 tcMETMuonCorrs_.push_back(t);
0434 embeddedTCMETMuonCorrs_ = true;
0435 }
0436
0437
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
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
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
0468 void Muon::readTimeExtra(const reco::MuonTimeExtra& t) {
0469 inverseBeta_ = t.inverseBeta();
0470 inverseBetaErr_ = t.inverseBetaErr();
0471 }
0472
0473
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
0488
0489
0490
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
0501
0502
0503
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
0514
0515 double Muon::dB(IpType type_) const {
0516
0517 if (cachedIP_ & (1 << int(type_))) {
0518 return ip_[type_];
0519 } else {
0520 return std::numeric_limits<double>::max();
0521 }
0522 }
0523
0524
0525
0526 double Muon::edB(IpType type_) const {
0527
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
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); }