rivet is hosted by Hepforge, IPPP Durham
Thrust.hh
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Thrust_HH
00003 #define RIVET_Thrust_HH
00004 
00005 #include "Rivet/Projection.hh"
00006 #include "Rivet/Projections/AxesDefinition.hh"
00007 #include "Rivet/Projections/FinalState.hh"
00008 #include "Rivet/Event.hh"
00009 
00010 namespace Rivet {
00011 
00012 
00013   /**
00014     @brief Get the e+ e- thrust basis and the thrust, thrust major and thrust minor scalars.
00015 
00016     @author Andy Buckley
00017 
00018     The scalar (maximum) thrust is defined as
00019     \f[
00020     T = \mathrm{max}_{\vec{n}} \frac{\sum_i \left|\vec{p}_i \cdot \vec{n} \right|}{\sum_i |\vec{p}_i|}
00021     \f],
00022     with the direction of the unit vector \f$ \vec{n} \f$ which maximises \f$ T \f$
00023     being identified as the thrust axis. The unit vector which maximises the thrust
00024     scalar in the plane perpendicular to \f$ \vec{n} \f$ is the "thrust major"
00025     direction, and the vector perpendicular to both the thrust and thrust major directions
00026     is the thrust minor. Both the major and minor directions have associated thrust
00027     scalars.
00028 
00029     Thrust calculations have particularly simple forms for less than 4 particles, and
00030     in those cases this projection is computationally minimal. For 4 or more particles,
00031     a more general calculation must be carried out, based on the Brandt/Dahmen method
00032     from Z. Phys. C1 (1978). While a polynomial improvement on the exponential scaling
00033     of the naive method, this algorithm scales asymptotically as
00034     \f$ \mathcal{O}\left( n^3 \right) \f$. Be aware that the thrust may easily be the
00035     most computationally demanding projection in Rivet for large events!
00036 
00037     The Rivet implementation of thrust is based heavily on Stefan Gieseke's Herwig++
00038     re-coding of the 'tasso' code from HERWIG.
00039 
00040     NB. special case with >= 4 coplanar particles will still fail.
00041     NB. Thrust assumes all momenta are in the CoM system: no explicit boost is performed.
00042       This can be dealt with by appropriate choice of the supplied FinalState.
00043    */
00044   class Thrust : public AxesDefinition {
00045   public:
00046 
00047     /// Constructor.
00048     Thrust() {}
00049 
00050     Thrust(const FinalState& fsp) {
00051       setName("Thrust");
00052       addProjection(fsp, "FS");
00053     }
00054 
00055     /// Clone on the heap.
00056     virtual const Projection* clone() const {
00057       return new Thrust(*this);
00058     }
00059 
00060   protected:
00061 
00062     /// Perform the projection on the Event
00063     void project(const Event& e) {
00064       const vector<Particle> ps
00065         = applyProjection<FinalState>(e, "FS").particles();
00066       calc(ps);
00067     }
00068 
00069     /// Compare projections
00070     int compare(const Projection& p) const {
00071       return mkNamedPCmp(p, "FS");
00072     }
00073 
00074 
00075   public:
00076 
00077     ///@{ Thrust scalar accessors
00078     /// The thrust scalar, \f$ T \f$, (maximum thrust).
00079     double thrust() const { return _thrusts[0]; }
00080     /// The thrust major scalar, \f$ M \f$, (thrust along thrust major axis).
00081     double thrustMajor() const { return _thrusts[1]; }
00082     /// The thrust minor scalar, \f$ m \f$, (thrust along thrust minor axis).
00083     double thrustMinor() const { return _thrusts[2]; }
00084     /// The oblateness, \f$ O = M - m \f$ .
00085     double oblateness() const { return _thrusts[1] - _thrusts[2]; }
00086     ///@}
00087 
00088     ///@{ Thrust axis accessors
00089     /// The thrust axis.
00090     const Vector3& thrustAxis() const { return _thrustAxes[0]; }
00091     /// The thrust major axis (axis of max thrust perpendicular to thrust axis).
00092     const Vector3& thrustMajorAxis() const { return _thrustAxes[1]; }
00093     /// The thrust minor axis (axis perpendicular to thrust and thrust major).
00094     const Vector3& thrustMinorAxis() const { return _thrustAxes[2]; }
00095     ///@}
00096 
00097     ///@{ AxesDefinition axis accessors.
00098     const Vector3& axis1() const { return thrustAxis(); }
00099     const Vector3& axis2() const { return thrustMajorAxis(); }
00100     const Vector3& axis3() const { return thrustMinorAxis(); }
00101     ///@}
00102 
00103 
00104   public:
00105 
00106     /// @name Direct methods
00107     /// Ways to do the calculation directly, without engaging the caching system
00108     //@{
00109 
00110     /// Manually calculate the thrust, without engaging the caching system
00111     void calc(const FinalState& fs);
00112 
00113     /// Manually calculate the thrust, without engaging the caching system
00114     void calc(const vector<Particle>& fsparticles);
00115 
00116     /// Manually calculate the thrust, without engaging the caching system
00117     void calc(const vector<FourMomentum>& fsmomenta);
00118 
00119     /// Manually calculate the thrust, without engaging the caching system
00120     void calc(const vector<Vector3>& threeMomenta);
00121 
00122     //@}
00123 
00124 
00125   private:
00126 
00127     /// The thrust scalars.
00128     vector<double> _thrusts;
00129 
00130     /// The thrust axes.
00131     vector<Vector3> _thrustAxes;
00132 
00133   private:
00134 
00135     /// Explicitly calculate the thrust values.
00136     void _calcThrust(const vector<Vector3>& fsmomenta);
00137 
00138   };
00139 
00140 }
00141 
00142 #endif