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 "DataFormats/Common/interface/BoolCache.h"
00006 #include "Utilities/General/interface/ClassName.h"
00007
00008 #include "DataFormats/PatCandidates/interface/Electron.h"
00009 #include "DataFormats/PatCandidates/interface/Muon.h"
00010 #include "DataFormats/PatCandidates/interface/Tau.h"
00011 #include "DataFormats/PatCandidates/interface/Photon.h"
00012 #include "DataFormats/PatCandidates/interface/Jet.h"
00013 #include "DataFormats/PatCandidates/interface/MET.h"
00014 #include "DataFormats/PatCandidates/interface/GenericParticle.h"
00015 #include "DataFormats/PatCandidates/interface/PFParticle.h"
00016
00017 namespace pat {
00018
00019
00020 class DiObjectProxy {
00021
00022 public:
00024 DiObjectProxy() : cand1_(0), cand2_(0), type1_(0), type2_(0) {}
00027 DiObjectProxy(const reco::Candidate &c1, const reco::Candidate &c2) :
00028 cand1_(&c1), cand2_(&c2), type1_(&typeid(c1)), type2_(&typeid(c2)) {}
00029
00031 const reco::Candidate & cand1() const { return *cand1_; }
00033 const reco::Candidate & cand2() const { return *cand2_; }
00034
00036 double deltaR() const { return ::deltaR(*cand1_, *cand2_); }
00038 double deltaPhi() const { return ::deltaPhi(cand1_->phi(), cand2_->phi()); }
00039
00041
00042
00043 const reco::Candidate::LorentzVector & totalP4() const {
00044 if (!totalP4ok_) {
00045 totalP4_ = cand1_->p4() + cand2_->p4();
00046 totalP4ok_ = true;
00047 }
00048 return totalP4_;
00049 }
00050
00052 const Electron & ele() const { return tryGetOne_<Electron>(); }
00054 const Muon & mu() const { return tryGetOne_<Muon>(); }
00056 const Tau & tau() const { return tryGetOne_<Tau>(); }
00058 const Photon & gam() const { return tryGetOne_<Photon>(); }
00060 const Jet & jet() const { return tryGetOne_<Jet>(); }
00062 const MET & met() const { return tryGetOne_<MET>(); }
00064 const GenericParticle & part() const { return tryGetOne_<GenericParticle>(); }
00066 const PFParticle & pf() const { return tryGetOne_<PFParticle>(); }
00067
00069 const Electron & ele1() const { return tryGet_<Electron>(cand1_, type1_); }
00071 const Muon & mu1() const { return tryGet_<Muon>(cand1_, type1_); }
00073 const Tau & tau1() const { return tryGet_<Tau>(cand1_, type1_); }
00075 const Photon & gam1() const { return tryGet_<Photon>(cand1_, type1_); }
00077 const Jet & jet1() const { return tryGet_<Jet>(cand1_, type1_); }
00079 const MET & met1() const { return tryGet_<MET>(cand1_, type1_); }
00081 const GenericParticle & part1() const { return tryGet_<GenericParticle>(cand1_, type1_); }
00083 const PFParticle & pf1() const { return tryGet_<PFParticle>(cand1_, type1_); }
00084
00086 const Electron & ele2() const { return tryGet_<Electron>(cand2_, type2_); }
00088 const Muon & mu2() const { return tryGet_<Muon>(cand2_, type2_); }
00090 const Tau & tau2() const { return tryGet_<Tau>(cand2_, type2_); }
00092 const Photon & gam2() const { return tryGet_<Photon>(cand2_, type2_); }
00094 const Jet & jet2() const { return tryGet_<Jet>(cand2_, type2_); }
00096 const MET & met2() const { return tryGet_<MET>(cand2_, type2_); }
00098 const GenericParticle & part2() const { return tryGet_<GenericParticle>(cand2_, type2_); }
00100 const PFParticle & pf2() const { return tryGet_<PFParticle>(cand2_, type2_); }
00101
00102 private:
00103
00104 template<typename T>
00105 const T & tryGet_(const reco::Candidate *ptr, const std::type_info *type) const {
00106 if (typeid(T) != *type) {
00107 throw cms::Exception("Type Error") << "pat::DiObjectProxy: the object of the pair is not of the type you request.\n"
00108 << " Item Index in pair: " << (ptr == cand1_ ? "first" : "second") << "\n"
00109 << " Requested TypeID : " << ClassName<T>::name() << "\n"
00110 << " Found TypeID : " << className(*ptr) << "\n";
00111 }
00112 return static_cast<const T &>(*ptr);
00113 }
00114
00115 template<typename T>
00116 const T & tryGetOne_() const {
00117 if (typeid(T) == *type1_) {
00118 if (typeid(T) == *type2_) {
00119 throw cms::Exception("Type Error") << "pat::DiObjectProxy: " <<
00120 "you can't get use methods that get a particle by type if the two are of the same type!\n" <<
00121 " Requested Type:" << ClassName<T>::name() << "\n";
00122 }
00123 return static_cast<const T &>(*cand1_);
00124 } else {
00125 if (typeid(T) != *type2_) {
00126 throw cms::Exception("Type Error") << "pat::DiObjectProxy: " <<
00127 "you can't get use methods that get a particle by type if neither of the two is of that type!\n" <<
00128 " Requested Type:" << ClassName<T>::name() << "\n" <<
00129 " Type of first :" << className(*cand1_) << "\n" <<
00130 " Type of second:" << className(*cand2_) << "\n";
00131 }
00132 return static_cast<const T &>(*cand2_);
00133 }
00134 }
00135
00136 const reco::Candidate *cand1_, *cand2_;
00137 const std::type_info *type1_, *type2_;
00138
00139 mutable edm::BoolCache totalP4ok_;
00140 mutable reco::Candidate::LorentzVector totalP4_;
00141
00142
00143 };
00144
00145 }
00146 #endif