CMS 3D CMS Logo

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