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