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 
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 }