00001
00002
00003
00004
00005 #include "DataFormats/PatCandidates/interface/Muon.h"
00006 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00007 #include "DataFormats/VertexReco/interface/Vertex.h"
00008 #include "FWCore/Utilities/interface/Exception.h"
00009
00010 #include <limits>
00011
00012 using namespace pat;
00013
00014
00016 Muon::Muon() :
00017 Lepton<reco::Muon>(),
00018 embeddedTrack_(false),
00019 embeddedStandAloneMuon_(false),
00020 embeddedCombinedMuon_(false),
00021 embeddedTCMETMuonCorrs_(false),
00022 embeddedCaloMETMuonCorrs_(false),
00023 embeddedPickyMuon_(false),
00024 embeddedTpfmsMuon_(false),
00025 embeddedDytMuon_(false),
00026 embeddedPFCandidate_(false),
00027 pfCandidateRef_(),
00028 cachedNormChi2_(false),
00029 cachedDB_(false),
00030 cachedNumberOfValidHits_(0),
00031 normChi2_(0.0),
00032 dB_(0.0),
00033 edB_(0.0),
00034 numberOfValidHits_(0)
00035 {
00036 initImpactParameters();
00037 }
00038
00040 Muon::Muon(const reco::Muon & aMuon) :
00041 Lepton<reco::Muon>(aMuon),
00042 embeddedTrack_(false),
00043 embeddedStandAloneMuon_(false),
00044 embeddedCombinedMuon_(false),
00045 embeddedTCMETMuonCorrs_(false),
00046 embeddedCaloMETMuonCorrs_(false),
00047 embeddedPickyMuon_(false),
00048 embeddedTpfmsMuon_(false),
00049 embeddedDytMuon_(false),
00050 embeddedPFCandidate_(false),
00051 pfCandidateRef_(),
00052 cachedNormChi2_(false),
00053 cachedDB_(false),
00054 cachedNumberOfValidHits_(0),
00055 normChi2_(0.0),
00056 dB_(0.0),
00057 edB_(0.0),
00058 numberOfValidHits_(0)
00059 {
00060 initImpactParameters();
00061 }
00062
00064 Muon::Muon(const edm::RefToBase<reco::Muon> & aMuonRef) :
00065 Lepton<reco::Muon>(aMuonRef),
00066 embeddedTrack_(false),
00067 embeddedStandAloneMuon_(false),
00068 embeddedCombinedMuon_(false),
00069 embeddedTCMETMuonCorrs_(false),
00070 embeddedCaloMETMuonCorrs_(false),
00071 embeddedPickyMuon_(false),
00072 embeddedTpfmsMuon_(false),
00073 embeddedDytMuon_(false),
00074 embeddedPFCandidate_(false),
00075 pfCandidateRef_(),
00076 cachedNormChi2_(false),
00077 cachedDB_(false),
00078 cachedNumberOfValidHits_(0),
00079 normChi2_(0.0),
00080 dB_(0.0),
00081 edB_(0.0),
00082 numberOfValidHits_(0)
00083 {
00084 initImpactParameters();
00085 }
00086
00088 Muon::Muon(const edm::Ptr<reco::Muon> & aMuonRef) :
00089 Lepton<reco::Muon>(aMuonRef),
00090 embeddedTrack_(false),
00091 embeddedStandAloneMuon_(false),
00092 embeddedCombinedMuon_(false),
00093 embeddedTCMETMuonCorrs_(false),
00094 embeddedCaloMETMuonCorrs_(false),
00095 embeddedPickyMuon_(false),
00096 embeddedTpfmsMuon_(false),
00097 embeddedDytMuon_(false),
00098 embeddedPFCandidate_(false),
00099 pfCandidateRef_(),
00100 cachedNormChi2_(false),
00101 cachedDB_(false),
00102 cachedNumberOfValidHits_(0),
00103 normChi2_(0.0),
00104 dB_(0.0),
00105 edB_(0.0),
00106 numberOfValidHits_(0)
00107 {
00108 initImpactParameters();
00109 }
00110
00112 Muon::~Muon() {
00113 }
00114
00115 std::ostream&
00116 reco::operator<<(std::ostream& out, const pat::Muon& obj)
00117 {
00118 if(!out) return out;
00119
00120 out << "\tpat::Muon: ";
00121 out << std::setiosflags(std::ios::right);
00122 out << std::setiosflags(std::ios::fixed);
00123 out << std::setprecision(3);
00124 out << " E/pT/eta/phi "
00125 << obj.energy()<<"/"
00126 << obj.pt()<<"/"
00127 << obj.eta()<<"/"
00128 << obj.phi();
00129 return out;
00130 }
00131
00132
00133 void Muon::initImpactParameters() {
00134 for (int i_ = 0; i_<5; ++i_){
00135 ip_.push_back(0.0);
00136 eip_.push_back(0.0);
00137 cachedIP_.push_back(false);
00138 }
00139 }
00140
00141
00143 reco::TrackRef Muon::track() const {
00144 if (embeddedTrack_) {
00145 return reco::TrackRef(&track_, 0);
00146 } else {
00147 return reco::Muon::innerTrack();
00148 }
00149 }
00150
00151
00153 reco::TrackRef Muon::standAloneMuon() const {
00154 if (embeddedStandAloneMuon_) {
00155 return reco::TrackRef(&standAloneMuon_, 0);
00156 } else {
00157 return reco::Muon::outerTrack();
00158 }
00159 }
00160
00161
00163 reco::TrackRef Muon::combinedMuon() const {
00164 if (embeddedCombinedMuon_) {
00165 return reco::TrackRef(&combinedMuon_, 0);
00166 } else {
00167 return reco::Muon::globalTrack();
00168 }
00169 }
00170
00172 reco::TrackRef Muon::pickyTrack() const {
00173 if (embeddedPickyMuon_) {
00174 return reco::TrackRef(&pickyMuon_, 0);
00175 } else {
00176 return reco::Muon::pickyTrack();
00177 }
00178 }
00179
00181 reco::TrackRef Muon::tpfmsTrack() const {
00182 if (embeddedTpfmsMuon_) {
00183 return reco::TrackRef(&tpfmsMuon_, 0);
00184 } else {
00185 return reco::Muon::tpfmsTrack();
00186 }
00187 }
00188
00190 reco::TrackRef Muon::dytTrack() const {
00191 if (embeddedDytMuon_) {
00192 return reco::TrackRef(&dytMuon_, 0);
00193 } else {
00194 return reco::Muon::dytTrack();
00195 }
00196 }
00197
00199 reco::PFCandidateRef Muon::pfCandidateRef() const {
00200 if (embeddedPFCandidate_) {
00201 return reco::PFCandidateRef(&pfCandidate_, 0);
00202 } else {
00203 return pfCandidateRef_;
00204 }
00205 }
00206
00208 reco::CandidatePtr Muon::sourceCandidatePtr( size_type i ) const {
00209 if (embeddedPFCandidate_) {
00210 return reco::CandidatePtr( pfCandidateRef_.id(), pfCandidateRef_.get(), pfCandidateRef_.key() );
00211 } else {
00212 return reco::CandidatePtr();
00213 }
00214 }
00215
00217 void Muon::embedMuonBestTrack() {
00218 muonBestTrack_.clear();
00219 if (reco::Muon::muonBestTrack().isNonnull()) {
00220 muonBestTrack_.push_back(*reco::Muon::muonBestTrack());
00221 embeddedMuonBestTrack_ = true;
00222 }
00223 }
00224
00225
00226
00228 void Muon::embedTrack() {
00229 track_.clear();
00230 if (reco::Muon::innerTrack().isNonnull()) {
00231 track_.push_back(*reco::Muon::innerTrack());
00232 embeddedTrack_ = true;
00233 }
00234 }
00235
00236
00238 void Muon::embedStandAloneMuon() {
00239 standAloneMuon_.clear();
00240 if (reco::Muon::outerTrack().isNonnull()) {
00241 standAloneMuon_.push_back(*reco::Muon::outerTrack());
00242 embeddedStandAloneMuon_ = true;
00243 }
00244 }
00245
00246
00248 void Muon::embedCombinedMuon() {
00249 combinedMuon_.clear();
00250 if (reco::Muon::globalTrack().isNonnull()) {
00251 combinedMuon_.push_back(*reco::Muon::globalTrack());
00252 embeddedCombinedMuon_ = true;
00253 }
00254 }
00255
00257 void Muon::embedCaloMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
00258 caloMETMuonCorrs_.clear();
00259 caloMETMuonCorrs_.push_back(t);
00260 embeddedCaloMETMuonCorrs_ = true;
00261 }
00262
00264 void Muon::embedTcMETMuonCorrs(const reco::MuonMETCorrectionData& t) {
00265 tcMETMuonCorrs_.clear();
00266 tcMETMuonCorrs_.push_back(t);
00267 embeddedTCMETMuonCorrs_ = true;
00268 }
00269
00271 void Muon::embedPickyMuon() {
00272 pickyMuon_.clear();
00273 reco::TrackRef tk = reco::Muon::pickyTrack();
00274 if (tk.isNonnull()) {
00275 pickyMuon_.push_back(*tk);
00276 embeddedPickyMuon_ = true;
00277 }
00278 }
00279
00281 void Muon::embedTpfmsMuon() {
00282 tpfmsMuon_.clear();
00283 reco::TrackRef tk = reco::Muon::tpfmsTrack();
00284 if (tk.isNonnull()) {
00285 tpfmsMuon_.push_back(*tk);
00286 embeddedTpfmsMuon_ = true;
00287 }
00288 }
00289
00291 void Muon::embedDytMuon() {
00292 dytMuon_.clear();
00293 reco::TrackRef tk = reco::Muon::dytTrack();
00294 if (tk.isNonnull()) {
00295 dytMuon_.push_back(*tk);
00296 embeddedDytMuon_ = true;
00297 }
00298 }
00299
00301 void Muon::embedPFCandidate() {
00302 pfCandidate_.clear();
00303 if ( pfCandidateRef_.isAvailable() && pfCandidateRef_.isNonnull()) {
00304 pfCandidate_.push_back( *pfCandidateRef_ );
00305 embeddedPFCandidate_ = true;
00306 }
00307 }
00308
00309 bool Muon::muonID(const std::string& name) const {
00310 muon::SelectionType st = muon::selectionTypeFromString(name);
00311 return muon::isGoodMuon(*this, st);
00312 }
00313
00314
00319 double Muon::normChi2() const {
00320 if ( cachedNormChi2_ ) {
00321 return normChi2_;
00322 } else {
00323 reco::TrackRef t = globalTrack();
00324 return t->chi2() / t->ndof();
00325 }
00326 }
00327
00332 unsigned int Muon::numberOfValidHits() const {
00333 if ( cachedNumberOfValidHits_ ) {
00334 return numberOfValidHits_;
00335 } else {
00336 reco::TrackRef t = innerTrack();
00337 return t->numberOfValidHits();
00338 }
00339 }
00340
00341
00342
00343
00344
00345 double Muon::dB(IpType type_) const {
00346
00347
00348 if (type_ == None){
00349 if ( cachedDB_ ) {
00350 return dB_;
00351 }
00352 else {
00353 return std::numeric_limits<double>::max();
00354 }
00355 }
00356
00357
00358 else if ( cachedIP_[type_] ) {
00359 return ip_[type_];
00360 } else {
00361 return std::numeric_limits<double>::max();
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370 double Muon::edB(IpType type_) const {
00371
00372
00373 if (type_ == None){
00374 if ( cachedDB_ ) {
00375 return edB_;
00376 }
00377 else {
00378 return std::numeric_limits<double>::max();
00379 }
00380 }
00381
00382
00383 else if ( cachedIP_[type_] ) {
00384 return eip_[type_];
00385 } else {
00386 return std::numeric_limits<double>::max();
00387 }
00388 }
00389
00390
00391 double Muon::segmentCompatibility(reco::Muon::ArbitrationType arbitrationType) const {
00392 return muon::segmentCompatibility(*this, arbitrationType);
00393 }
00394
00395
00396 bool Muon::isTightMuon(const reco::Vertex&vtx) const {
00397 return muon::isTightMuon(*this,vtx);
00398 }
00399
00400
00401
00402 bool Muon::isLooseMuon() const{
00403 return isPFMuon() && (isGlobalMuon() || isTrackerMuon());
00404 }
00405
00406
00407 bool Muon::isSoftMuon(const reco::Vertex& vtx) const{
00408
00409 bool muID = muon::isGoodMuon(*this,muon::TMOneStationTight);
00410
00411 if(!muID) return false;
00412
00413 bool layers = innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
00414 innerTrack()->hitPattern().pixelLayersWithMeasurement() > 1;
00415
00416 bool chi2 = innerTrack()->normalizedChi2() < 1.8;
00417
00418 bool ip = fabs(innerTrack()->dxy(vtx.position())) < 3. && fabs(innerTrack()->dz(vtx.position())) < 30.;
00419
00420 return muID && layers && ip && chi2 ;
00421 }
00422
00423
00424 bool Muon::isHighPtMuon(const reco::Vertex& vtx) const{
00425 bool muID = isGlobalMuon() && globalTrack()->hitPattern().numberOfValidMuonHits() >0 && (numberOfMatchedStations() > 1);
00426 if(!muID) return false;
00427
00428 bool hits = innerTrack()->hitPattern().trackerLayersWithMeasurement() > 8 &&
00429 innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
00430
00431 bool ip = fabs(muonBestTrack()->dxy(vtx.position())) < 0.2 && fabs(bestTrack()->dz(vtx.position())) < 0.5;
00432
00433 return muID && hits && ip;
00434
00435 }
00436