Hemispheres.hh

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Hemispheres_HH
00003 #define RIVET_Hemispheres_HH
00004 
00005 #include "Rivet/Projection.hh"
00006 #include "Rivet/Projections/FinalState.hh"
00007 #include "Rivet/Projections/AxesDefinition.hh"
00008 #include "Rivet/Event.hh"
00009 
00010 
00011 namespace Rivet {
00012 
00013   /**
00014      @brief Calculate the hemisphere masses and broadenings.
00015 
00016      Calculate the hemisphere masses and broadenings, with event hemispheres
00017      defined by the plane normal to the thrust vector, \f$ \vec{n}_\mathrm{T} \f$.
00018 
00019      @todo Allow axes to be defined by sphericity: superclass Thrust and Sphericity as AxisDefinition?
00020 
00021      The "high" hemisphere mass,
00022      \f$ M^2_\mathrm{high} / E^2_\mathrm{vis} \f$, is defined as
00023      \f[
00024      \frac{M^2_\mathrm{high}}{E^2_\mathrm{vis}} =
00025      \frac{1}{E^2_\mathrm{vis}} \max
00026      \left(
00027      \left| \sum_{\vec{p}_k \cdot \vec{n}_\mathrm{T} > 0} p_k \right|^2 ,
00028      \left| \sum_{\vec{p}_k \cdot \vec{n}_\mathrm{T} < 0} p_k \right|^2
00029      \right)
00030      \f]
00031      and the corresponding "low" hemisphere mass,
00032      \f$ M^2_\mathrm{low} / E^2_\mathrm{vis} \f$,
00033      is the sum of momentum vectors in the opposite hemisphere, i.e.
00034      \f$ \max \rightarrow \min \f$ in the formula above.
00035 
00036      Finally, we define a hemisphere mass difference:
00037      \f[
00038      \frac{M^2_\mathrm{diff} }{ E^2_\mathrm{vis}} =
00039      \frac{ M^2_\mathrm{high} - M^2_\mathrm{low} }{ E^2_\mathrm{vis}} .
00040      \f]
00041 
00042      Similarly to the masses, we also define hemisphere broadenings, using the
00043      momenta transverse to the thrust axis:
00044      \f[
00045      B_\pm =
00046      \frac{
00047        \sum{\pm \vec{p}_i \cdot \vec{n}_\mathrm{T} > 0}
00048        |\vec{p}_i \times \vec{n}_\mathrm{T} |
00049      }{
00050        2 \sum_i | \vec{p}_i |
00051      }
00052      \f]
00053      and then a set of the broadening maximum, minimum, sum and difference as follows:
00054      \f[ B_\mathrm{max}  = \max(B_+, B_-) \f]
00055      \f[ B_\mathrm{min}  = \min(B_+, B_-) \f]
00056      \f[ B_\mathrm{sum}  = B_+ + B_- \f]
00057      \f[ B_\mathrm{diff} = |B_+ - B_-| \f]
00058 
00059      Internally, this projection uses a Thrust or Sphericity projection to
00060      determine the hemisphere orientation.
00061   */
00062   class Hemispheres : public Projection {
00063   public:
00064 
00065     /// Constructor.
00066     Hemispheres(const AxesDefinition& ax) {
00067       setName("Hemispheres");
00068       addProjection(ax, "Axes");
00069       clear();
00070     }
00071 
00072     /// Clone on the heap.
00073     virtual const Projection* clone() const {
00074       return new Hemispheres(*this);
00075     }
00076 
00077     // Reset the projection
00078     void clear() {
00079       _E2vis = -1;
00080       _M2high = -1;
00081       _M2low = -1;
00082       _Bmax = -1;
00083       _Bmin = -1;
00084       _highMassEqMaxBroad = true;
00085     }
00086 
00087 
00088   protected:
00089 
00090     /// Perform the projection on the Event.
00091     void project(const Event& e);
00092 
00093     /// Compare with other projections.
00094     int compare(const Projection& p) const {
00095       return mkNamedPCmp(p, "Axes");
00096     }
00097 
00098 
00099   public:
00100 
00101     /// @name Hemisphere masses (scaled by \f$ 1 / E^2_\mathrm{vis} \f$).
00102     //@{
00103 
00104     double E2vis() const { return _E2vis; }
00105     double Evis() const { return sqrt(_E2vis); }
00106 
00107     double M2high() const { return _M2high; }
00108     double Mhigh() const { return sqrt(M2high()); }
00109 
00110     double M2low() const { return _M2low; }
00111     double Mlow() const { return sqrt(M2low()); }
00112 
00113     double M2diff() const { return _M2high -_M2low; }
00114     double Mdiff() const { return sqrt(M2diff()); }
00115 
00116     double scaledM2high() const {
00117       if (_M2high == 0.0) return 0.0;
00118       if (_E2vis != 0.0) return _M2high/_E2vis;
00119       else return std::numeric_limits<double>::max();
00120     }
00121     double scaledMhigh() const { return sqrt(scaledM2high()); }
00122 
00123     double scaledM2low() const {
00124       if (_M2low == 0.0) return 0.0;
00125       if (_E2vis != 0.0) return _M2low/_E2vis;
00126       else return std::numeric_limits<double>::max();
00127     }
00128     double scaledMlow() const { return sqrt(scaledM2low()); }
00129 
00130     double scaledM2diff() const {
00131       if (M2diff() == 0.0) return 0.0;
00132       if (_E2vis != 0.0) return M2diff()/_E2vis;
00133       else return std::numeric_limits<double>::max();
00134     }
00135     double scaledMdiff() const { return sqrt(scaledM2diff()); }
00136     //@}
00137 
00138 
00139     /// @name Hemisphere broadenings.
00140     //@{
00141     double Bmax() const { return _Bmax; }
00142     double Bmin() const { return _Bmin; }
00143     double Bsum() const { return _Bmax + _Bmin; }
00144     double Bdiff() const { return fabs(_Bmax - _Bmin); } // <- fabs(), just in case...
00145     //@}
00146 
00147 
00148     /// Is the hemisphere with the max mass the same as the one with the max broadening?
00149     bool massMatchesBroadening() {
00150       return _highMassEqMaxBroad;
00151     }
00152 
00153      
00154   private:
00155 
00156     /// Visible energy-squared, \f$ E^2_\mathrm{vis} \f$.
00157     double _E2vis;
00158 
00159     /// Hemisphere mass variables.
00160     double _M2high, _M2low;
00161 
00162     /// Hemisphere broadening variables.
00163     double _Bmax, _Bmin;
00164 
00165     /// Is the hemisphere with the max mass the same as the one with the max broadening?
00166     bool _highMassEqMaxBroad;
00167 
00168   };
00169 
00170 
00171 }
00172 
00173 #endif