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