/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PhysicsTools/PatUtils/interface/PATDiObjectProxy.h
145 строк
7 KB
Cms Build
Clang-Format
05 июн 2019, 13:58
05 июн 2019, 13:58
4bb99cd
Код
Авторство
О чём код?
#ifndef PhysicsTools_PatUtils_interface_PATDiObjectProxy_h #define PhysicsTools_PatUtils_interface_PATDiObjectProxy_h #include "DataFormats/Math/interface/deltaR.h" #include "Utilities/General/interface/ClassName.h" #include "DataFormats/PatCandidates/interface/Electron.h" #include "DataFormats/PatCandidates/interface/Muon.h" #include "DataFormats/PatCandidates/interface/Tau.h" #include "DataFormats/PatCandidates/interface/Photon.h" #include "DataFormats/PatCandidates/interface/Jet.h" #include "DataFormats/PatCandidates/interface/MET.h" #include "DataFormats/PatCandidates/interface/GenericParticle.h" #include "DataFormats/PatCandidates/interface/PFParticle.h" namespace pat { /* Now we implement PATDiObjectProxy with typeid & static_casts on the fly. */ class DiObjectProxy { public: /// Default constructor, requested by ROOT. NEVER use a default constructed item! DiObjectProxy() : cand1_(nullptr), cand2_(nullptr), type1_(nullptr), type2_(nullptr), totalP4ok_(false), totalP4_() {} /// Constructor of the pair from two Candidates /// Note: the Proxy MUST NOT outlive the Candidates, otherwise you get dangling pointers DiObjectProxy(const reco::Candidate &c1, const reco::Candidate &c2) : cand1_(&c1), cand2_(&c2), type1_(&typeid(c1)), type2_(&typeid(c2)), totalP4ok_(false), totalP4_() {} /// Gets the first Candidate const reco::Candidate &cand1() const { return *cand1_; } /// Gets the second Candidate const reco::Candidate &cand2() const { return *cand2_; } /// Get the angular separation double deltaR() const { return ::deltaR(*cand1_, *cand2_); } /// Get the phi separation double deltaPhi() const { return ::deltaPhi(cand1_->phi(), cand2_->phi()); } /// Get the total four momentum // Implementation notice: return by const reference, not by value, // as it's easier for Reflex. const reco::Candidate::LorentzVector &totalP4() const { if (!totalP4ok_) { totalP4_ = cand1_->p4() + cand2_->p4(); totalP4ok_ = true; } return totalP4_; } /// Get the PAT Electron, if the pair contains one and only one PAT Electron (throw exception otherwise) const Electron &ele() const { return tryGetOne_<Electron>(); } /// Get the PAT Muon, if the pair contains one and only one PAT Muon (throw exception otherwise) const Muon &mu() const { return tryGetOne_<Muon>(); } /// Get the PAT Tau, if the pair contains one and only one PAT Tau (throw exception otherwise) const Tau &tau() const { return tryGetOne_<Tau>(); } /// Get the PAT Photon, if the pair contains one and only one PAT Photon (throw exception otherwise) const Photon &gam() const { return tryGetOne_<Photon>(); } /// Get the PAT Jet, if the pair contains one and only one PAT Jet (throw exception otherwise) const Jet &jet() const { return tryGetOne_<Jet>(); } /// Get the PAT MET, if the pair contains one and only one PAT MET (throw exception otherwise) const MET &met() const { return tryGetOne_<MET>(); } /// Get the PAT GenericParticle, if the pair contains one and only one PAT GenericParticle (throw exception otherwise) const GenericParticle &part() const { return tryGetOne_<GenericParticle>(); } /// Get the PAT PFParticle, if the pair contains one and only one PAT PFParticle (throw exception otherwise) const PFParticle &pf() const { return tryGetOne_<PFParticle>(); } /// Get the first item, if it's a PAT Electron (throw exception otherwise) const Electron &ele1() const { return tryGet_<Electron>(cand1_, type1_); } /// Get the first item, if it's a PAT Muon (throw exception otherwise) const Muon &mu1() const { return tryGet_<Muon>(cand1_, type1_); } /// Get the first item, if it's a PAT Tau (throw exception otherwise) const Tau &tau1() const { return tryGet_<Tau>(cand1_, type1_); } /// Get the first item, if it's a PAT Photon (throw exception otherwise) const Photon &gam1() const { return tryGet_<Photon>(cand1_, type1_); } /// Get the first item, if it's a PAT Jet (throw exception otherwise) const Jet &jet1() const { return tryGet_<Jet>(cand1_, type1_); } /// Get the first item, if it's a PAT MET (throw exception otherwise) const MET &met1() const { return tryGet_<MET>(cand1_, type1_); } /// Get the first item, if it's a PAT GenericParticle (throw exception otherwise) const GenericParticle &part1() const { return tryGet_<GenericParticle>(cand1_, type1_); } /// Get the first item, if it's a PAT PFParticle (throw exception otherwise) const PFParticle &pf1() const { return tryGet_<PFParticle>(cand1_, type1_); } /// Get the second item, if it's a PAT Electron (throw exception otherwise) const Electron &ele2() const { return tryGet_<Electron>(cand2_, type2_); } /// Get the second item, if it's a PAT Muon (throw exception otherwise) const Muon &mu2() const { return tryGet_<Muon>(cand2_, type2_); } /// Get the second item, if it's a PAT Tau (throw exception otherwise) const Tau &tau2() const { return tryGet_<Tau>(cand2_, type2_); } /// Get the second item, if it's a PAT Photon (throw exception otherwise) const Photon &gam2() const { return tryGet_<Photon>(cand2_, type2_); } /// Get the second item, if it's a PAT Jet (throw exception otherwise) const Jet &jet2() const { return tryGet_<Jet>(cand2_, type2_); } /// Get the second item, if it's a PAT MET (throw exception otherwise) const MET &met2() const { return tryGet_<MET>(cand2_, type2_); } /// Get the second item, if it's a PAT GenericParticle (throw exception otherwise) const GenericParticle &part2() const { return tryGet_<GenericParticle>(cand2_, type2_); } /// Get the second item, if it's a PAT PFParticle (throw exception otherwise) const PFParticle &pf2() const { return tryGet_<PFParticle>(cand2_, type2_); } private: template <typename T> const T &tryGet_(const reco::Candidate *ptr, const std::type_info *type) const { if (typeid(T) != *type) { throw cms::Exception("Type Error") << "pat::DiObjectProxy: the object of the pair is not of the type you request.\n" << " Item Index in pair: " << (ptr == cand1_ ? "first" : "second") << "\n" << " Requested TypeID : " << ClassName<T>::name() << "\n" << " Found TypeID : " << className(*ptr) << "\n"; } return static_cast<const T &>(*ptr); } template <typename T> const T &tryGetOne_() const { if (typeid(T) == *type1_) { if (typeid(T) == *type2_) { throw cms::Exception("Type Error") << "pat::DiObjectProxy: " << "you can't get use methods that get a particle by type if the two are of the same type!\n" << " Requested Type:" << ClassName<T>::name() << "\n"; } return static_cast<const T &>(*cand1_); } else { if (typeid(T) != *type2_) { throw cms::Exception("Type Error") << "pat::DiObjectProxy: " << "you can't get use methods that get a particle by type if neither of the two is of that type!\n" << " Requested Type:" << ClassName<T>::name() << "\n" << " Type of first :" << className(*cand1_) << "\n" << " Type of second:" << className(*cand2_) << "\n"; } return static_cast<const T &>(*cand2_); } } const reco::Candidate *cand1_, *cand2_; const std::type_info *type1_, *type2_; mutable bool totalP4ok_; mutable reco::Candidate::LorentzVector totalP4_; }; } // namespace pat #endif