CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/PhysicsTools/PatUtils/interface/PATDiObjectProxy.h

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 /* Now we implement PATDiObjectProxy with typeid & static_casts on the fly. */
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         // Implementation notice: return by const reference, not by value, 
00042         // as it's easier for Reflex.
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