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     DEFAULT_RIVET_PROJ_CLONE(Thrust);
00057 
00058   protected:
00059 
00060     /// Perform the projection on the Event
00061     void project(const Event& e) {
00062       const vector<Particle> ps
00063         = applyProjection<FinalState>(e, "FS").particles();
00064       calc(ps);
00065     }
00066 
00067     /// Compare projections
00068     int compare(const Projection& p) const {
00069       return mkNamedPCmp(p, "FS");
00070     }
00071 
00072 
00073   public:
00074 
00075     ///@{ Thrust scalar accessors
00076     /// The thrust scalar, \f$ T \f$, (maximum thrust).
00077     double thrust() const { return _thrusts[0]; }
00078     /// The thrust major scalar, \f$ M \f$, (thrust along thrust major axis).
00079     double thrustMajor() const { return _thrusts[1]; }
00080     /// The thrust minor scalar, \f$ m \f$, (thrust along thrust minor axis).
00081     double thrustMinor() const { return _thrusts[2]; }
00082     /// The oblateness, \f$ O = M - m \f$ .
00083     double oblateness() const { return _thrusts[1] - _thrusts[2]; }
00084     ///@}
00085 
00086     ///@{ Thrust axis accessors
00087     /// The thrust axis.
00088     const Vector3& thrustAxis() const { return _thrustAxes[0]; }
00089     /// The thrust major axis (axis of max thrust perpendicular to thrust axis).
00090     const Vector3& thrustMajorAxis() const { return _thrustAxes[1]; }
00091     /// The thrust minor axis (axis perpendicular to thrust and thrust major).
00092     const Vector3& thrustMinorAxis() const { return _thrustAxes[2]; }
00093     ///@}
00094 
00095     ///@{ AxesDefinition axis accessors.
00096     const Vector3& axis1() const { return thrustAxis(); }
00097     const Vector3& axis2() const { return thrustMajorAxis(); }
00098     const Vector3& axis3() const { return thrustMinorAxis(); }
00099     ///@}
00100 
00101 
00102   public:
00103 
00104     /// @name Direct methods
00105     /// Ways to do the calculation directly, without engaging the caching system
00106     //@{
00107 
00108     /// Manually calculate the thrust, without engaging the caching system
00109     void calc(const FinalState& fs);
00110 
00111     /// Manually calculate the thrust, without engaging the caching system
00112     void calc(const vector<Particle>& fsparticles);
00113 
00114     /// Manually calculate the thrust, without engaging the caching system
00115     void calc(const vector<FourMomentum>& fsmomenta);
00116 
00117     /// Manually calculate the thrust, without engaging the caching system
00118     void calc(const vector<Vector3>& threeMomenta);
00119 
00120     //@}
00121 
00122 
00123   private:
00124 
00125     /// The thrust scalars.
00126     vector<double> _thrusts;
00127 
00128     /// The thrust axes.
00129     vector<Vector3> _thrustAxes;
00130 
00131   private:
00132 
00133     /// Explicitly calculate the thrust values.
00134     void _calcThrust(const vector<Vector3>& fsmomenta);
00135 
00136   };
00137 
00138 }
00139 
00140 #endif