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