Go to the documentation of this file.00001 #ifndef PhysicsTools_PatUtils_interface_PATDiObjectProxy_h
00002 #define PhysicsTools_PatUtils_interface_PATDiObjectProxy_h
00003
00004 #include "DataFormats/Math/interface/deltaR.h"
00005 #include "Utilities/General/interface/ClassName.h"
00006
00007 #include "DataFormats/PatCandidates/interface/Electron.h"
00008 #include "DataFormats/PatCandidates/interface/Muon.h"
00009 #include "DataFormats/PatCandidates/interface/Tau.h"
00010 #include "DataFormats/PatCandidates/interface/Photon.h"
00011 #include "DataFormats/PatCandidates/interface/Jet.h"
00012 #include "DataFormats/PatCandidates/interface/MET.h"
00013 #include "DataFormats/PatCandidates/interface/GenericParticle.h"
00014 #include "DataFormats/PatCandidates/interface/PFParticle.h"
00015
00016 namespace pat {
00017
00018
00019 class DiObjectProxy {
00020
00021 public:
00023 DiObjectProxy() : cand1_(0), cand2_(0), type1_(0), type2_(0), totalP4ok_(false), totalP4_() {}
00026 DiObjectProxy(const reco::Candidate &c1, const reco::Candidate &c2) :
00027 cand1_(&c1), cand2_(&c2), type1_(&typeid(c1)), type2_(&typeid(c2)), totalP4ok_(false), totalP4_() {}
00028
00030 const reco::Candidate & cand1() const { return *cand1_; }
00032 const reco::Candidate & cand2() const { return *cand2_; }
00033
00035 double deltaR() const { return ::deltaR(*cand1_, *cand2_); }
00037 double deltaPhi() const { return ::deltaPhi(cand1_->phi(), cand2_->phi()); }
00038
00040
00041
00042 const reco::Candidate::LorentzVector & totalP4() const {
00043 if (!totalP4ok_) {
00044 totalP4_ = cand1_->p4() + cand2_->p4();
00045 totalP4ok_ = true;
00046 }
00047 return totalP4_;
00048 }
00049
00051 const Electron & ele() const { return tryGetOne_<Electron>(); }
00053 const Muon & mu() const { return tryGetOne_<Muon>(); }
00055 const Tau & tau() const { return tryGetOne_<Tau>(); }
00057 const Photon & gam() const { return tryGetOne_<Photon>(); }
00059 const Jet & jet() const { return tryGetOne_<Jet>(); }
00061 const MET & met() const { return tryGetOne_<MET>(); }
00063 const GenericParticle & part() const { return tryGetOne_<GenericParticle>(); }
00065 const PFParticle & pf() const { return tryGetOne_<PFParticle>(); }
00066
00068 const Electron & ele1() const { return tryGet_<Electron>(cand1_, type1_); }
00070 const Muon & mu1() const { return tryGet_<Muon>(cand1_, type1_); }
00072 const Tau & tau1() const { return tryGet_<Tau>(cand1_, type1_); }
00074 const Photon & gam1() const { return tryGet_<Photon>(cand1_, type1_); }
00076 const Jet & jet1() const { return tryGet_<Jet>(cand1_, type1_); }
00078 const MET & met1() const { return tryGet_<MET>(cand1_, type1_); }
00080 const GenericParticle & part1() const { return tryGet_<GenericParticle>(cand1_, type1_); }
00082 const PFParticle & pf1() const { return tryGet_<PFParticle>(cand1_, type1_); }
00083
00085 const Electron & ele2() const { return tryGet_<Electron>(cand2_, type2_); }
00087 const Muon & mu2() const { return tryGet_<Muon>(cand2_, type2_); }
00089 const Tau & tau2() const { return tryGet_<Tau>(cand2_, type2_); }
00091 const Photon & gam2() const { return tryGet_<Photon>(cand2_, type2_); }
00093 const Jet & jet2() const { return tryGet_<Jet>(cand2_, type2_); }
00095 const MET & met2() const { return tryGet_<MET>(cand2_, type2_); }
00097 const GenericParticle & part2() const { return tryGet_<GenericParticle>(cand2_, type2_); }
00099 const PFParticle & pf2() const { return tryGet_<PFParticle>(cand2_, type2_); }
00100
00101 private:
00102
00103 template<typename T>
00104 const T & tryGet_(const reco::Candidate *ptr, const std::type_info *type) const {
00105 if (typeid(T) != *type) {
00106 throw cms::Exception("Type Error") << "pat::DiObjectProxy: the object of the pair is not of the type you request.\n"
00107 << " Item Index in pair: " << (ptr == cand1_ ? "first" : "second") << "\n"
00108 << " Requested TypeID : " << ClassName<T>::name() << "\n"
00109 << " Found TypeID : " << className(*ptr) << "\n";
00110 }
00111 return static_cast<const T &>(*ptr);
00112 }
00113
00114 template<typename T>
00115 const T & tryGetOne_() const {
00116 if (typeid(T) == *type1_) {
00117 if (typeid(T) == *type2_) {
00118 throw cms::Exception("Type Error") << "pat::DiObjectProxy: " <<
00119 "you can't get use methods that get a particle by type if the two are of the same type!\n" <<
00120 " Requested Type:" << ClassName<T>::name() << "\n";
00121 }
00122 return static_cast<const T &>(*cand1_);
00123 } else {
00124 if (typeid(T) != *type2_) {
00125 throw cms::Exception("Type Error") << "pat::DiObjectProxy: " <<
00126 "you can't get use methods that get a particle by type if neither of the two is of that type!\n" <<
00127 " Requested Type:" << ClassName<T>::name() << "\n" <<
00128 " Type of first :" << className(*cand1_) << "\n" <<
00129 " Type of second:" << className(*cand2_) << "\n";
00130 }
00131 return static_cast<const T &>(*cand2_);
00132 }
00133 }
00134
00135 const reco::Candidate *cand1_, *cand2_;
00136 const std::type_info *type1_, *type2_;
00137
00138 mutable bool totalP4ok_;
00139 mutable reco::Candidate::LorentzVector totalP4_;
00140
00141
00142 };
00143
00144 }
00145 #endif