File indexing completed on 2024-04-06 12:24:04
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
0019 class DiObjectProxy {
0020 public:
0021
0022 DiObjectProxy()
0023 : cand1_(nullptr), cand2_(nullptr), type1_(nullptr), type2_(nullptr), totalP4ok_(false), totalP4_() {}
0024
0025
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
0030 const reco::Candidate &cand1() const { return *cand1_; }
0031
0032 const reco::Candidate &cand2() const { return *cand2_; }
0033
0034
0035 double deltaR() const { return ::deltaR(*cand1_, *cand2_); }
0036
0037 double deltaPhi() const { return ::deltaPhi(cand1_->phi(), cand2_->phi()); }
0038
0039
0040
0041
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
0051 const Electron &ele() const { return tryGetOne_<Electron>(); }
0052
0053 const Muon &mu() const { return tryGetOne_<Muon>(); }
0054
0055 const Tau &tau() const { return tryGetOne_<Tau>(); }
0056
0057 const Photon &gam() const { return tryGetOne_<Photon>(); }
0058
0059 const Jet &jet() const { return tryGetOne_<Jet>(); }
0060
0061 const MET &met() const { return tryGetOne_<MET>(); }
0062
0063 const GenericParticle &part() const { return tryGetOne_<GenericParticle>(); }
0064
0065 const PFParticle &pf() const { return tryGetOne_<PFParticle>(); }
0066
0067
0068 const Electron &ele1() const { return tryGet_<Electron>(cand1_, type1_); }
0069
0070 const Muon &mu1() const { return tryGet_<Muon>(cand1_, type1_); }
0071
0072 const Tau &tau1() const { return tryGet_<Tau>(cand1_, type1_); }
0073
0074 const Photon &gam1() const { return tryGet_<Photon>(cand1_, type1_); }
0075
0076 const Jet &jet1() const { return tryGet_<Jet>(cand1_, type1_); }
0077
0078 const MET &met1() const { return tryGet_<MET>(cand1_, type1_); }
0079
0080 const GenericParticle &part1() const { return tryGet_<GenericParticle>(cand1_, type1_); }
0081
0082 const PFParticle &pf1() const { return tryGet_<PFParticle>(cand1_, type1_); }
0083
0084
0085 const Electron &ele2() const { return tryGet_<Electron>(cand2_, type2_); }
0086
0087 const Muon &mu2() const { return tryGet_<Muon>(cand2_, type2_); }
0088
0089 const Tau &tau2() const { return tryGet_<Tau>(cand2_, type2_); }
0090
0091 const Photon &gam2() const { return tryGet_<Photon>(cand2_, type2_); }
0092
0093 const Jet &jet2() const { return tryGet_<Jet>(cand2_, type2_); }
0094
0095 const MET &met2() const { return tryGet_<MET>(cand2_, type2_); }
0096
0097 const GenericParticle &part2() const { return tryGet_<GenericParticle>(cand2_, type2_); }
0098
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 }
0145 #endif