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 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     NB. special case with >= 4 coplanar particles will still fail.
00043     NB. Thrust assumes all momenta are in the CoM system: no explicit boost is performed.
00044       This can be dealt with by appropriate choice of the supplied FinalState.
00045    */
00046   class Thrust : public AxesDefinition {
00047   public:
00048 
00049     /// Constructor.
00050     Thrust(const FinalState& fsp)
00051       : _calculatedThrust(false)
00052     {
00053       setName("Thrust");
00054       addProjection(fsp, "FS");
00055     }
00056 
00057     /// Clone on the heap.
00058     virtual const Projection* clone() const {
00059       return new Thrust(*this);
00060     }
00061 
00062   protected:
00063 
00064     /// Perform the projection on the Event
00065     void project(const Event& e) {
00066       const vector<Particle> ps
00067         = applyProjection<FinalState>(e, "FS").particles();
00068       calc(ps);
00069     }
00070 
00071     /// Compare projections
00072     int compare(const Projection& p) const {
00073       return mkNamedPCmp(p, "FS");
00074     }
00075 
00076 
00077   public:
00078 
00079     ///@{ Thrust scalar accessors
00080     /// The thrust scalar, \f$ T \f$, (maximum thrust).
00081     double thrust() const { return _thrusts[0]; }
00082     /// The thrust major scalar, \f$ M \f$, (thrust along thrust major axis).
00083     double thrustMajor() const { return _thrusts[1]; }
00084     /// The thrust minor scalar, \f$ m \f$, (thrust along thrust minor axis).
00085     double thrustMinor() const { return _thrusts[2]; }
00086     /// The oblateness, \f$ O = M - m \f$ .
00087     double oblateness() const { return _thrusts[1] - _thrusts[2]; }
00088     ///@}
00089 
00090     ///@{ Thrust axis accessors
00091     /// The thrust axis.
00092     const Vector3& thrustAxis() const { return _thrustAxes[0]; }
00093     /// The thrust major axis (axis of max thrust perpendicular to thrust axis).
00094     const Vector3& thrustMajorAxis() const { return _thrustAxes[1]; }
00095     /// The thrust minor axis (axis perpendicular to thrust and thrust major).
00096     const Vector3& thrustMinorAxis() const { return _thrustAxes[2]; }
00097     ///@}
00098 
00099     ///@{ AxesDefinition axis accessors.
00100     const Vector3& axis1() const { return thrustAxis(); }
00101     const Vector3& axis2() const { return thrustMajorAxis(); }
00102     const Vector3& axis3() const { return thrustMinorAxis(); }
00103     ///@}
00104 
00105 
00106   public:
00107 
00108     /// @name Direct methods
00109     /// Ways to do the calculation directly, without engaging the caching system
00110     //@{
00111 
00112     /// Manually calculate the thrust, without engaging the caching system
00113     void calc(const FinalState& fs);
00114 
00115     /// Manually calculate the thrust, without engaging the caching system
00116     void calc(const vector<Particle>& fsparticles);
00117 
00118     /// Manually calculate the thrust, without engaging the caching system
00119     void calc(const vector<FourMomentum>& fsmomenta);
00120    
00121     /// Manually calculate the thrust, without engaging the caching system
00122     void calc(const vector<Vector3>& threeMomenta);
00123 
00124     //@}
00125 
00126 
00127   private:
00128 
00129     /// The thrust scalars.
00130     vector<double> _thrusts;
00131 
00132     /// The thrust axes.
00133     vector<Vector3> _thrustAxes;
00134 
00135     /// Caching flag to avoid costly recalculations.
00136     bool _calculatedThrust;
00137 
00138   private:
00139 
00140     /// Explicitly calculate the thrust values.
00141     void _calcThrust(const vector<Vector3>& fsmomenta);
00142 
00143   };
00144 
00145 }
00146 
00147 #endif