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 Cuts::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::absrap: return std::abs(p_.momentum().rapidity()); 00265 case Cuts::eta: return p_.momentum().pseudorapidity(); 00266 case Cuts::abseta: return std::abs(p_.momentum().pseudorapidity()); 00267 case Cuts::phi: return p_.momentum().phi(); 00268 default: qty_not_found(); 00269 } 00270 return -999.; 00271 } 00272 private: 00273 const Particle & p_; 00274 }; 00275 SPECIALISE_ACCEPT(Particle) 00276 00277 00278 template<> 00279 class Cuttable <FourMomentum> : public CuttableBase { 00280 public: 00281 Cuttable(const FourMomentum& fm) : fm_(fm) {} 00282 double getValue(Cuts::Quantity qty) const { 00283 switch ( qty ) { 00284 case Cuts::pT: return fm_.pT(); 00285 case Cuts::mass: return fm_.mass(); 00286 case Cuts::rap: return fm_.rapidity(); 00287 case Cuts::absrap: return std::abs(fm_.rapidity()); 00288 case Cuts::eta: return fm_.pseudorapidity(); 00289 case Cuts::abseta: return std::abs(fm_.pseudorapidity()); 00290 case Cuts::phi: return fm_.phi(); 00291 default: qty_not_found(); 00292 } 00293 return -999.; 00294 } 00295 private: 00296 const FourMomentum & fm_; 00297 }; 00298 SPECIALISE_ACCEPT(FourMomentum) 00299 00300 template<> 00301 class Cuttable <Jet> : public CuttableBase { 00302 public: 00303 Cuttable(const Jet& jet) : jet_(jet) {} 00304 double getValue(Cuts::Quantity qty) const { 00305 switch ( qty ) { 00306 case Cuts::pT: return jet_.momentum().pT(); 00307 case Cuts::mass: return jet_.momentum().mass(); 00308 case Cuts::rap: return jet_.momentum().rapidity(); 00309 case Cuts::absrap: return std::abs(jet_.momentum().rapidity()); 00310 case Cuts::eta: return jet_.momentum().pseudorapidity(); 00311 case Cuts::abseta: return std::abs(jet_.momentum().pseudorapidity()); 00312 case Cuts::phi: return jet_.momentum().phi(); 00313 default: qty_not_found(); 00314 } 00315 return -999.; 00316 } 00317 private: 00318 const Jet & jet_; 00319 }; 00320 SPECIALISE_ACCEPT(Jet) 00321 00322 template<> 00323 class Cuttable <fastjet::PseudoJet> : public CuttableBase { 00324 public: 00325 Cuttable(const fastjet::PseudoJet& pjet) : pjet_(pjet) {} 00326 double getValue(Cuts::Quantity qty) const { 00327 switch ( qty ) { 00328 case Cuts::pT: return pjet_.perp(); 00329 case Cuts::mass: return pjet_.m(); 00330 case Cuts::rap: return pjet_.rap(); 00331 case Cuts::absrap: return std::abs(pjet_.rap()); 00332 case Cuts::eta: return pjet_.eta(); 00333 case Cuts::abseta: return std::abs(pjet_.eta()); 00334 case Cuts::phi: return pjet_.phi(); 00335 default: qty_not_found(); 00336 } 00337 return -999.; 00338 } 00339 private: 00340 const fastjet::PseudoJet & pjet_; 00341 }; 00342 SPECIALISE_ACCEPT(fastjet::PseudoJet) 00343 00344 00345 template<> 00346 class Cuttable <HepMC::FourVector> : public CuttableBase { 00347 public: 00348 Cuttable(const HepMC::FourVector & vec) : vec_(vec) {} 00349 double getValue(Cuts::Quantity qty) const { 00350 switch ( qty ) { 00351 case Cuts::pT: return vec_.perp(); 00352 case Cuts::mass: return vec_.m(); 00353 case Cuts::rap: return 0.5*std::log((vec_.t()+vec_.z())/(vec_.t()-vec_.z())); 00354 case Cuts::absrap: return std::abs(getValue(Cuts::rap)); 00355 case Cuts::eta: return vec_.pseudoRapidity(); 00356 case Cuts::abseta: return std::abs(vec_.pseudoRapidity()); 00357 case Cuts::phi: return vec_.phi(); 00358 default: qty_not_found(); 00359 } 00360 return -999.; 00361 } 00362 private: 00363 const HepMC::FourVector & vec_; 00364 }; 00365 SPECIALISE_ACCEPT(HepMC::FourVector) 00366 00367 } Generated on Tue Sep 30 2014 19:45:44 for The Rivet MC analysis system by ![]() |