00001 // -*- C++ -*- 00002 #ifndef RIVET_Thrust_HH 00003 #define RIVET_Thrust_HH 00004 00005 #include "Rivet/Projection.hh" 00006 #include "Rivet/Projections/FinalState.hh" 00007 #include "Rivet/Event.hh" 00008 #include "Rivet/RivetCLHEP.hh" 00009 00010 00011 namespace Rivet { 00012 00013 /** 00014 @brief Obtain the e+ e- thrust event shape, consisting of the thrust basis and the 00015 thrust scalar values in each direction (the thrust, thrust major and thrust 00016 minor). 00017 00018 @author Andy Buckley 00019 00020 The scalar (maximum) thrust is defined as 00021 \f[ 00022 T = \mathrm{max}_{\vec{n}} \frac{\sum_i \left|\vec{p}_i \cdot \vec{n} \right|}{\sum_i |\vec{p}_i|} 00023 \f], 00024 with the direction of the unit vector \f$ \vec{n} \f$ which maximises \f$ T \f$ 00025 being identified as the thrust axis. The unit vector which maximises the thrust 00026 scalar in the plane perpendicular to \f$ \vec{n} \f$ is the "thrust major" 00027 direction, and the vector perpendicular to both the thrust and thrust major directions 00028 is the thrust minor. Both the major and minor directions have associated thrust 00029 scalars. 00030 00031 Thrust calculations have particularly simple forms for less than 4 particles, and 00032 in those cases this projection is computationally minimal. For 4 or more particles, 00033 a more general calculation must be carried out, based on the Brandt/Dahmen method 00034 from Z. Phys. C1 (1978). While a polynomial improvement on the exponential scaling 00035 of the naive method, this algorithm scales asymptotically as 00036 \f$ \mathcal{O}\left( n^3 \right) \f$. Be aware that the thrust may easily be the 00037 most computationally demanding projection in Rivet for large events! 00038 00039 The Rivet implementation of thrust is based heavily on Stefan Gieseke's Herwig++ 00040 re-coding of the 'tasso' code from HERWIG. 00041 */ 00042 class Thrust : public Projection { 00043 public: 00044 00045 /// Constructor. The FinalState projection must live throughout the run. 00046 inline Thrust(FinalState& fsp) 00047 : _calculatedThrust(false), _fsproj(&fsp) 00048 { 00049 addProjection(fsp); 00050 } 00051 00052 /// Return the name of the projection 00053 inline string getName() const { 00054 return "Thrust"; 00055 } 00056 00057 00058 protected: 00059 00060 /// Perform the projection on the Event 00061 void project(const Event& e); 00062 00063 /// Compare projections 00064 inline int compare(const Projection& p) const { 00065 return 0; 00066 } 00067 00068 00069 public: 00070 00071 ///@{ Thrust scalar accessors 00072 /// The thrust scalar, \f$ T \f$, (maximum thrust). 00073 inline const double thrust() const { return _thrusts[0]; } 00074 /// The thrust major scalar, \f$ M \f$, (thrust along thrust major axis). 00075 inline const double thrustMajor() const { return _thrusts[1]; } 00076 /// The thrust minor scalar, \f$ m \f$, (thrust along thrust minor axis). 00077 inline const double thrustMinor() const { return _thrusts[2]; } 00078 /// The oblateness, \f$ O = M - m \f$ . 00079 inline const double oblateness() const { return _thrusts[1] - _thrusts[2]; } 00080 ///@} 00081 00082 ///@{ Thrust axis accessors 00083 /// The thrust axis. 00084 inline const Vector3& thrustAxis() const { return _thrustAxes[0]; } 00085 /// The thrust major axis (axis of max thrust perpendicular to thrust axis). 00086 inline const Vector3& thrustMajorAxis() const { return _thrustAxes[1]; } 00087 /// The thrust minor axis (axis perpendicular to thrust and thrust major). 00088 inline const Vector3& thrustMinorAxis() const { return _thrustAxes[2]; } 00089 ///@} 00090 00091 00092 private: 00093 00094 /// The thrust scalars. 00095 vector<double> _thrusts; 00096 00097 /// The thrust axes. 00098 vector<Vector3> _thrustAxes; 00099 00100 /// Caching flag to avoid costly recalculations. 00101 bool _calculatedThrust; 00102 00103 /// The FinalState projection used by this projection 00104 FinalState* _fsproj; 00105 00106 00107 private: 00108 00109 /// Calculate the thrust axes and scalars, using special cases where possible. 00110 void calcThrust(const FinalState& fs); 00111 00112 /// Explicitly calculate the thrust minor value and axis. 00113 void calcM(const vector<Vector3>& p, double& m, Vector3& maxis) const; 00114 00115 /// Explicitly calculate the thrust value and axis. 00116 void calcT(const vector<Vector3>& p, double& t, Vector3& taxis) const; 00117 00118 }; 00119 00120 } 00121 00122 00123 #endif