rivet is hosted by Hepforge, IPPP Durham
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 }