Cuts.cc
Go to the documentation of this file.
00001 #include <Rivet/Cuts.hh> 00002 #include <boost/make_shared.hpp> 00003 00004 // headers for converters 00005 #include <Rivet/Particle.hh> 00006 #include <Rivet/Jet.hh> 00007 #include <Rivet/Math/Vectors.hh> 00008 #include <fastjet/PseudoJet.hh> 00009 #include <HepMC/SimpleVector.h> 00010 00011 // todo Sort out what can go into anonymous namespace{} 00012 00013 namespace Rivet { 00014 00015 // Base for all wrapper classes that translate ClassToCheck to Cuttable 00016 class CuttableBase { 00017 public: 00018 virtual double getValue(Cuts::Quantity) const = 0; 00019 virtual ~CuttableBase() {} 00020 }; 00021 00022 00023 // Cuttables can be directly passed to @ref accept_ 00024 template <> 00025 bool CutBase::accept<CuttableBase>(const CuttableBase & t) const { 00026 return accept_(t); 00027 } 00028 00029 // bool operator==(const Cut & a, const Cut & b) { 00030 // return *a == b; 00031 // } 00032 00033 00034 // Open Cut singleton 00035 class Open_Cut : public CutBase { 00036 public: 00037 bool operator==(const Cut & c) const { 00038 shared_ptr<Open_Cut> cc = dynamic_pointer_cast<Open_Cut>(c); 00039 return bool(cc); 00040 } 00041 protected: 00042 // open cut accepts everything 00043 bool accept_(const CuttableBase &) const { return true; } 00044 }; 00045 00046 const Cut & Cuts::open() { 00047 // only ever need one static open cut object 00048 static const Cut open = boost::make_shared<Open_Cut>(); 00049 return open; 00050 } 00051 00052 00053 00054 00055 00056 // Cut constructor for >= 00057 class Cut_GtrEq : public CutBase { 00058 public: 00059 Cut_GtrEq(const Cuts::Quantity qty, const double low) : qty_(qty), low_(low) {} 00060 bool operator==(const Cut & c) const { 00061 shared_ptr<Cut_GtrEq> cc = dynamic_pointer_cast<Cut_GtrEq>(c); 00062 return cc && qty_ == cc->qty_ && low_ == cc->low_; 00063 } 00064 protected: 00065 bool accept_(const CuttableBase & o) const { return o.getValue(qty_) >= low_; } 00066 private: 00067 Cuts::Quantity qty_; 00068 double low_; 00069 }; 00070 00071 // Cut constructor for < 00072 class Cut_Less : public CutBase { 00073 public: 00074 Cut_Less(const Cuts::Quantity qty, const double high) : qty_(qty), high_(high) {} 00075 bool operator==(const Cut & c) const { 00076 shared_ptr<Cut_Less> cc = dynamic_pointer_cast<Cut_Less>(c); 00077 return cc && qty_ == cc->qty_ && high_ == cc->high_; 00078 } 00079 protected: 00080 bool accept_(const CuttableBase & o) const { return o.getValue(qty_) < high_; } 00081 private: 00082 Cuts::Quantity qty_; 00083 double high_; 00084 }; 00085 00086 // Cut constructor for >= 00087 class Cut_Gtr : public CutBase { 00088 public: 00089 Cut_Gtr(const Cuts::Quantity qty, const double low) : qty_(qty), low_(low) {} 00090 bool operator==(const Cut & c) const { 00091 shared_ptr<Cut_Gtr> cc = dynamic_pointer_cast<Cut_Gtr>(c); 00092 return cc && qty_ == cc->qty_ && low_ == cc->low_; 00093 } 00094 protected: 00095 bool accept_(const CuttableBase & o) const { return o.getValue(qty_) > low_; } 00096 private: 00097 Cuts::Quantity qty_; 00098 double low_; 00099 }; 00100 00101 // Cut constructor for < 00102 class Cut_LessEq : public CutBase { 00103 public: 00104 Cut_LessEq(const Cuts::Quantity qty, const double high) : qty_(qty), high_(high) {} 00105 bool operator==(const Cut & c) const { 00106 shared_ptr<Cut_LessEq> cc = dynamic_pointer_cast<Cut_LessEq>(c); 00107 return cc && qty_ == cc->qty_ && high_ == cc->high_; 00108 } 00109 protected: 00110 bool accept_(const CuttableBase & o) const { return o.getValue(qty_) <= high_; } 00111 private: 00112 Cuts::Quantity qty_; 00113 double high_; 00114 }; 00115 00116 00117 template <typename T> 00118 inline Cut make_cut(T t) { 00119 return boost::make_shared<T>(t); 00120 } 00121 00122 Cut operator < (Cuts::Quantity qty, double n) { 00123 return make_cut(Cut_Less(qty, n)); 00124 } 00125 00126 Cut operator >= (Cuts::Quantity qty, double n) { 00127 return make_cut(Cut_GtrEq(qty, n)); 00128 } 00129 00130 Cut operator <= (Cuts::Quantity qty, double n) { 00131 return make_cut(Cut_LessEq(qty, n)); 00132 } 00133 00134 Cut operator > (Cuts::Quantity qty, double n) { 00135 return make_cut(Cut_Gtr(qty, n)); 00136 } 00137 00138 Cut Range(Cuts::Quantity qty, double m, double n) { 00139 if (m > n) swap(m,n); 00140 return (qty >= m) & (qty < n); 00141 } 00142 00143 00144 ////////////// 00145 /// Combiners 00146 00147 /// AND, OR, NOT, and XOR objects for combining cuts 00148 00149 class CutsOr : public CutBase { 00150 public: 00151 CutsOr(const Cut c1, const Cut c2) : cut1(c1), cut2(c2) {} 00152 bool operator==(const Cut & c) const { 00153 shared_ptr<CutsOr> cc = dynamic_pointer_cast<CutsOr>(c); 00154 return cc && ( ( cut1 == cc->cut1 && cut2 == cc->cut2 ) 00155 || ( cut1 == cc->cut2 && cut2 == cc->cut1 )); 00156 } 00157 protected: 00158 bool accept_(const CuttableBase & o) const { 00159 return cut1->accept(o) || cut2->accept(o); 00160 } 00161 private: 00162 const Cut cut1; 00163 const Cut cut2; 00164 }; 00165 00166 class CutsAnd : public CutBase { 00167 public: 00168 CutsAnd(const Cut c1, const Cut c2) : cut1(c1), cut2(c2) {} 00169 bool operator==(const Cut & c) const { 00170 shared_ptr<CutsAnd> cc = dynamic_pointer_cast<CutsAnd>(c); 00171 return cc && ( ( cut1 == cc->cut1 && cut2 == cc->cut2 ) 00172 || ( cut1 == cc->cut2 && cut2 == cc->cut1 )); 00173 } 00174 protected: 00175 bool accept_(const CuttableBase & o) const { 00176 return cut1->accept(o) && cut2->accept(o); 00177 } 00178 private: 00179 const Cut cut1; 00180 const Cut cut2; 00181 }; 00182 00183 class CutInvert : public CutBase { 00184 public: 00185 CutInvert(const Cut c1) : cut(c1) {} 00186 bool operator==(const Cut & c) const { 00187 shared_ptr<CutInvert> cc = dynamic_pointer_cast<CutInvert>(c); 00188 return cc && cut == cc->cut; 00189 } 00190 protected: 00191 bool accept_(const CuttableBase & o) const { 00192 return !cut->accept(o); 00193 } 00194 private: 00195 const Cut cut; 00196 }; 00197 00198 class CutsXor : public CutBase { 00199 public: 00200 CutsXor(const Cut c1, const Cut c2) : cut1(c1), cut2(c2) {} 00201 bool operator==(const Cut & c) const { 00202 shared_ptr<CutsXor> cc = dynamic_pointer_cast<CutsXor>(c); 00203 return cc && ( ( cut1 == cc->cut1 && cut2 == cc->cut2 ) 00204 || ( cut1 == cc->cut2 && cut2 == cc->cut1 )); 00205 } 00206 protected: 00207 bool accept_(const CuttableBase & o) const { 00208 bool A_and_B = cut1->accept(o) && cut2->accept(o); 00209 bool A_or_B = cut1->accept(o) || cut2->accept(o); 00210 return A_or_B && (! A_and_B); 00211 } 00212 private: 00213 const Cut cut1; 00214 const Cut cut2; 00215 }; 00216 00217 //////////// 00218 ///Operators 00219 00220 Cut operator & (const Cut aptr, const Cut bptr) { 00221 return make_cut(CutsAnd(aptr,bptr)); 00222 } 00223 00224 Cut operator | (const Cut aptr, const Cut bptr) { 00225 return make_cut(CutsOr(aptr,bptr)); 00226 } 00227 00228 Cut operator ~ (const Cut cptr) { 00229 return make_cut(CutInvert(cptr)); 00230 } 00231 00232 Cut operator ^ (const Cut aptr, const Cut bptr) { 00233 return make_cut(CutsXor(aptr,bptr)); 00234 } 00235 00236 /////////////////////// 00237 /// Cuts 00238 00239 // Non-functional Cuttable template class. Must be specialized below. 00240 template <typename T> class Cuttable; 00241 00242 // Non-cuttables need to be wrapped into a Cuttable first 00243 #define SPECIALISE_ACCEPT(TYPENAME) \ 00244 template <> \ 00245 bool CutBase::accept<TYPENAME>(const TYPENAME & t) const { \ 00246 return accept_(Cuttable<TYPENAME>(t)); \ 00247 } \ 00248 00249 00250 void qty_not_found() { 00251 throw Exception("Missing implementation for a Cuts::Quantity."); 00252 } 00253 00254 00255 template<> 00256 class Cuttable <Particle> : public CuttableBase { 00257 public: 00258 Cuttable(const Particle& p) : p_(p) {} 00259 double getValue(Cuts::Quantity qty) const { 00260 switch ( qty ) { 00261 case Cuts::pT: return p_.momentum().pT(); 00262 case Cuts::mass: return p_.momentum().mass(); 00263 case Cuts::rap: return p_.momentum().rapidity(); 00264 case Cuts::eta: return p_.momentum().pseudorapidity(); 00265 case Cuts::phi: return p_.momentum().phi(); 00266 default: qty_not_found(); 00267 } 00268 return -999.; 00269 } 00270 private: 00271 const Particle & p_; 00272 }; 00273 SPECIALISE_ACCEPT(Particle) 00274 00275 00276 template<> 00277 class Cuttable <FourMomentum> : public CuttableBase { 00278 public: 00279 Cuttable(const FourMomentum& fm) : fm_(fm) {} 00280 double getValue(Cuts::Quantity qty) const { 00281 switch ( qty ) { 00282 case Cuts::pT: return fm_.pT(); 00283 case Cuts::mass: return fm_.mass(); 00284 case Cuts::rap: return fm_.rapidity(); 00285 case Cuts::eta: return fm_.pseudorapidity(); 00286 case Cuts::phi: return fm_.phi(); 00287 default: qty_not_found(); 00288 } 00289 return -999.; 00290 } 00291 private: 00292 const FourMomentum & fm_; 00293 }; 00294 SPECIALISE_ACCEPT(FourMomentum) 00295 00296 template<> 00297 class Cuttable <Jet> : public CuttableBase { 00298 public: 00299 Cuttable(const Jet& jet) : jet_(jet) {} 00300 double getValue(Cuts::Quantity qty) const { 00301 switch ( qty ) { 00302 case Cuts::pT: return jet_.momentum().pT(); 00303 case Cuts::mass: return jet_.momentum().mass(); 00304 case Cuts::rap: return jet_.momentum().rapidity(); 00305 case Cuts::eta: return jet_.momentum().pseudorapidity(); 00306 case Cuts::phi: return jet_.momentum().phi(); 00307 default: qty_not_found(); 00308 } 00309 return -999.; 00310 } 00311 private: 00312 const Jet & jet_; 00313 }; 00314 SPECIALISE_ACCEPT(Jet) 00315 00316 template<> 00317 class Cuttable <fastjet::PseudoJet> : public CuttableBase { 00318 public: 00319 Cuttable(const fastjet::PseudoJet& pjet) : pjet_(pjet) {} 00320 double getValue(Cuts::Quantity qty) const { 00321 switch ( qty ) { 00322 case Cuts::pT: return pjet_.perp(); 00323 case Cuts::mass: return pjet_.m(); 00324 case Cuts::rap: return pjet_.rap(); 00325 case Cuts::eta: return pjet_.eta(); 00326 case Cuts::phi: return pjet_.phi(); 00327 default: qty_not_found(); 00328 } 00329 return -999.; 00330 } 00331 private: 00332 const fastjet::PseudoJet & pjet_; 00333 }; 00334 SPECIALISE_ACCEPT(fastjet::PseudoJet) 00335 00336 00337 template<> 00338 class Cuttable <HepMC::FourVector> : public CuttableBase { 00339 public: 00340 Cuttable(const HepMC::FourVector & vec) : vec_(vec) {} 00341 double getValue(Cuts::Quantity qty) const { 00342 switch ( qty ) { 00343 case Cuts::pT: return vec_.perp(); 00344 case Cuts::mass: return vec_.m(); 00345 // case Cuts::rap: return vec_.rap(); // needs calculated conversion 00346 case Cuts::eta: return vec_.pseudoRapidity(); 00347 case Cuts::phi: return vec_.phi(); 00348 default: qty_not_found(); 00349 } 00350 return -999.; 00351 } 00352 private: 00353 const HepMC::FourVector & vec_; 00354 }; 00355 SPECIALISE_ACCEPT(HepMC::FourVector) 00356 00357 } Generated on Thu Feb 6 2014 17:38:44 for The Rivet MC analysis system by ![]() |