Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:33:10

0001 #ifndef PhysicsTools_PatUtils_interface_PATDiObjectProxy_h
0002 #define PhysicsTools_PatUtils_interface_PATDiObjectProxy_h
0003 
0004 #include "DataFormats/Math/interface/deltaR.h"
0005 #include "Utilities/General/interface/ClassName.h"
0006 
0007 #include "DataFormats/PatCandidates/interface/Electron.h"
0008 #include "DataFormats/PatCandidates/interface/Muon.h"
0009 #include "DataFormats/PatCandidates/interface/Tau.h"
0010 #include "DataFormats/PatCandidates/interface/Photon.h"
0011 #include "DataFormats/PatCandidates/interface/Jet.h"
0012 #include "DataFormats/PatCandidates/interface/MET.h"
0013 #include "DataFormats/PatCandidates/interface/GenericParticle.h"
0014 #include "DataFormats/PatCandidates/interface/PFParticle.h"
0015 
0016 namespace pat {
0017 
0018   /* Now we implement PATDiObjectProxy with typeid & static_casts on the fly. */
0019   class DiObjectProxy {
0020   public:
0021     /// Default constructor, requested by ROOT. NEVER use a default constructed item!
0022     DiObjectProxy()
0023         : cand1_(nullptr), cand2_(nullptr), type1_(nullptr), type2_(nullptr), totalP4ok_(false), totalP4_() {}
0024     /// Constructor of the pair from two Candidates
0025     /// Note: the Proxy MUST NOT outlive the Candidates, otherwise you get dangling pointers
0026     DiObjectProxy(const reco::Candidate &c1, const reco::Candidate &c2)
0027         : cand1_(&c1), cand2_(&c2), type1_(&typeid(c1)), type2_(&typeid(c2)), totalP4ok_(false), totalP4_() {}
0028 
0029     /// Gets the first Candidate
0030     const reco::Candidate &cand1() const { return *cand1_; }
0031     /// Gets the second Candidate
0032     const reco::Candidate &cand2() const { return *cand2_; }
0033 
0034     /// Get the angular separation
0035     double deltaR() const { return ::deltaR(*cand1_, *cand2_); }
0036     /// Get the phi separation
0037     double deltaPhi() const { return ::deltaPhi(cand1_->phi(), cand2_->phi()); }
0038 
0039     /// Get the total four momentum
0040     // Implementation notice: return by const reference, not by value,
0041     // as it's easier for Reflex.
0042     const reco::Candidate::LorentzVector &totalP4() const {
0043       if (!totalP4ok_) {
0044         totalP4_ = cand1_->p4() + cand2_->p4();
0045         totalP4ok_ = true;
0046       }
0047       return totalP4_;
0048     }
0049 
0050     /// Get the PAT Electron, if the pair contains one and only one PAT Electron (throw exception otherwise)
0051     const Electron &ele() const { return tryGetOne_<Electron>(); }
0052     /// Get the PAT Muon, if the pair contains one and only one PAT Muon (throw exception otherwise)
0053     const Muon &mu() const { return tryGetOne_<Muon>(); }
0054     /// Get the PAT Tau, if the pair contains one and only one PAT Tau (throw exception otherwise)
0055     const Tau &tau() const { return tryGetOne_<Tau>(); }
0056     /// Get the PAT Photon, if the pair contains one and only one PAT Photon (throw exception otherwise)
0057     const Photon &gam() const { return tryGetOne_<Photon>(); }
0058     /// Get the PAT Jet, if the pair contains one and only one PAT Jet (throw exception otherwise)
0059     const Jet &jet() const { return tryGetOne_<Jet>(); }
0060     /// Get the PAT MET, if the pair contains one and only one PAT MET (throw exception otherwise)
0061     const MET &met() const { return tryGetOne_<MET>(); }
0062     /// Get the PAT GenericParticle, if the pair contains one and only one PAT GenericParticle (throw exception otherwise)
0063     const GenericParticle &part() const { return tryGetOne_<GenericParticle>(); }
0064     /// Get the PAT PFParticle, if the pair contains one and only one PAT PFParticle (throw exception otherwise)
0065     const PFParticle &pf() const { return tryGetOne_<PFParticle>(); }
0066 
0067     /// Get the first item, if it's a PAT Electron (throw exception otherwise)
0068     const Electron &ele1() const { return tryGet_<Electron>(cand1_, type1_); }
0069     /// Get the first item, if it's a PAT Muon (throw exception otherwise)
0070     const Muon &mu1() const { return tryGet_<Muon>(cand1_, type1_); }
0071     /// Get the first item, if it's a PAT Tau (throw exception otherwise)
0072     const Tau &tau1() const { return tryGet_<Tau>(cand1_, type1_); }
0073     /// Get the first item, if it's a PAT Photon (throw exception otherwise)
0074     const Photon &gam1() const { return tryGet_<Photon>(cand1_, type1_); }
0075     /// Get the first item, if it's a PAT Jet (throw exception otherwise)
0076     const Jet &jet1() const { return tryGet_<Jet>(cand1_, type1_); }
0077     /// Get the first item, if it's a PAT MET (throw exception otherwise)
0078     const MET &met1() const { return tryGet_<MET>(cand1_, type1_); }
0079     /// Get the first item, if it's a PAT GenericParticle (throw exception otherwise)
0080     const GenericParticle &part1() const { return tryGet_<GenericParticle>(cand1_, type1_); }
0081     /// Get the first item, if it's a PAT PFParticle (throw exception otherwise)
0082     const PFParticle &pf1() const { return tryGet_<PFParticle>(cand1_, type1_); }
0083 
0084     /// Get the second item, if it's a PAT Electron (throw exception otherwise)
0085     const Electron &ele2() const { return tryGet_<Electron>(cand2_, type2_); }
0086     /// Get the second item, if it's a PAT Muon (throw exception otherwise)
0087     const Muon &mu2() const { return tryGet_<Muon>(cand2_, type2_); }
0088     /// Get the second item, if it's a PAT Tau (throw exception otherwise)
0089     const Tau &tau2() const { return tryGet_<Tau>(cand2_, type2_); }
0090     /// Get the second item, if it's a PAT Photon (throw exception otherwise)
0091     const Photon &gam2() const { return tryGet_<Photon>(cand2_, type2_); }
0092     /// Get the second item, if it's a PAT Jet (throw exception otherwise)
0093     const Jet &jet2() const { return tryGet_<Jet>(cand2_, type2_); }
0094     /// Get the second item, if it's a PAT MET (throw exception otherwise)
0095     const MET &met2() const { return tryGet_<MET>(cand2_, type2_); }
0096     /// Get the second item, if it's a PAT GenericParticle (throw exception otherwise)
0097     const GenericParticle &part2() const { return tryGet_<GenericParticle>(cand2_, type2_); }
0098     /// Get the second item, if it's a PAT PFParticle (throw exception otherwise)
0099     const PFParticle &pf2() const { return tryGet_<PFParticle>(cand2_, type2_); }
0100 
0101   private:
0102     template <typename T>
0103     const T &tryGet_(const reco::Candidate *ptr, const std::type_info *type) const {
0104       if (typeid(T) != *type) {
0105         throw cms::Exception("Type Error")
0106             << "pat::DiObjectProxy: the object of the pair is not of the type you request.\n"
0107             << " Item Index in pair: " << (ptr == cand1_ ? "first" : "second") << "\n"
0108             << " Requested TypeID  : " << ClassName<T>::name() << "\n"
0109             << " Found TypeID      : " << className(*ptr) << "\n";
0110       }
0111       return static_cast<const T &>(*ptr);
0112     }
0113 
0114     template <typename T>
0115     const T &tryGetOne_() const {
0116       if (typeid(T) == *type1_) {
0117         if (typeid(T) == *type2_) {
0118           throw cms::Exception("Type Error")
0119               << "pat::DiObjectProxy: "
0120               << "you can't get use methods that get a particle by type if the two are of the same type!\n"
0121               << " Requested Type:" << ClassName<T>::name() << "\n";
0122         }
0123         return static_cast<const T &>(*cand1_);
0124       } else {
0125         if (typeid(T) != *type2_) {
0126           throw cms::Exception("Type Error")
0127               << "pat::DiObjectProxy: "
0128               << "you can't get use methods that get a particle by type if neither of the two is of that type!\n"
0129               << " Requested Type:" << ClassName<T>::name() << "\n"
0130               << " Type of first :" << className(*cand1_) << "\n"
0131               << " Type of second:" << className(*cand2_) << "\n";
0132         }
0133         return static_cast<const T &>(*cand2_);
0134       }
0135     }
0136 
0137     const reco::Candidate *cand1_, *cand2_;
0138     const std::type_info *type1_, *type2_;
0139 
0140     mutable bool totalP4ok_;
0141     mutable reco::Candidate::LorentzVector totalP4_;
0142   };
0143 
0144 }  // namespace pat
0145 #endif