rivet is hosted by Hepforge, IPPP Durham
Spherocity.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Rivet.hh"
00003 #include "Rivet/Projections/Spherocity.hh"
00004 #include "Rivet/Tools/Logging.hh"
00005 
00006 
00007 namespace Rivet {
00008 
00009 
00010   void Spherocity::calc(const FinalState& fs) {
00011     calc(fs.particles());
00012   }
00013 
00014 
00015   void Spherocity::calc(const vector<Particle>& fsparticles) {
00016     vector<Vector3> threeMomenta;
00017     threeMomenta.reserve(fsparticles.size());
00018     foreach (const Particle& p, fsparticles) {
00019       const Vector3 p3 = p.momentum().vector3();
00020       threeMomenta.push_back(p3);
00021     }
00022     _calcSpherocity(threeMomenta);
00023   }
00024 
00025 
00026   void Spherocity::calc(const vector<FourMomentum>& fsmomenta) {
00027     vector<Vector3> threeMomenta;
00028     threeMomenta.reserve(fsmomenta.size());
00029     foreach (const FourMomentum& v, fsmomenta) {
00030       threeMomenta.push_back(v.vector3());
00031     }
00032     _calcSpherocity(threeMomenta);
00033   }
00034 
00035 
00036   void Spherocity::calc(const vector<Vector3>& fsmomenta) {
00037     _calcSpherocity(fsmomenta);
00038   }
00039 
00040 
00041   /////////////////////////////////////////////////
00042 
00043 
00044   //// Do the general case spherocity calculation
00045   void _calcS(const vector<Vector3 >& perpmomenta, double& sphero, Vector3& saxis) {
00046     // According to the Salam paper, p5, footnote 4, the
00047     // axis n that minimises the Spherocity value ALWAYS coincides with the
00048     // direction of one of the transverse momentum vectors of the events particles.
00049     // Thus we carry out the calculation of Sphero for all particles and pick the
00050     // one that yields the smallerst values
00051 
00052     vector<Vector3> p = perpmomenta;
00053     vector<double> sval;
00054 
00055     // Prepare vector to store unit vector representation of all particle momenta
00056     vector<Vector3> units;
00057     foreach (const Vector3& p, perpmomenta) {
00058       units.push_back(Vector3(p.x(), p.y(), 0.0).unit());
00059     }
00060 
00061     // Spherocity calculation
00062     //
00063     // Pick the solution with the smallest spherocity
00064     sphero = 99999.;
00065     // The outer loop is for iteration over all unit vectors
00066     foreach (const Vector3& u, units){
00067       double s =0.0;
00068       for (unsigned int k=0 ; k<p.size() ; k++) {
00069         s += fabs( p[k].cross(u).mod() );
00070       }
00071       if (s < sphero) {
00072         sphero = s;
00073         saxis = u;
00074       }
00075     }
00076   }
00077 
00078   // Do the full calculation
00079   void Spherocity::_calcSpherocity(const vector<Vector3>& fsmomenta) {
00080 
00081     // Make a vector of the three-momenta in the final state
00082     // Explicitly set the z-component (parallel to beam axis) to zero
00083     // This creates a 3D-vector representation of the transverse momentum
00084     // but takes the full information momentum vectors as input
00085 
00086     // A small iteration over full momenta but set z-coord. to 0.0 to get transverse momenta
00087     vector<Vector3> fsperpmomenta;
00088     foreach (const Vector3& p, fsmomenta) {
00089       fsperpmomenta.push_back(Vector3(p.x(), p.y(), 0.0));
00090     }
00091 
00092     // This returns the scalar sum of (transverse) momenta
00093     double perpmomentumSum(0.0);
00094     foreach (const Vector3& p, fsperpmomenta) {
00095       perpmomentumSum += mod(p);
00096     }
00097 
00098     // Clear the caches
00099     _spherocities.clear();
00100     _spherocityAxes.clear();
00101 
00102 
00103     // Temporary variables for calcs
00104     Vector3 axis(0,0,0);
00105     double val = 0.;
00106 
00107     // Get spherocity
00108     _calcS(fsperpmomenta, val, axis);
00109     MSG_DEBUG("Mom sum = " << perpmomentumSum);
00110     double spherocity = 0.25 * PI * PI * val * val / (perpmomentumSum * perpmomentumSum);
00111     _spherocities.push_back(spherocity);
00112 
00113     // See if calculated spherocity value makes sense
00114     if (spherocity < 0.0 || spherocity > 1.0) {
00115       MSG_WARNING("Spherocity = " << spherocity);
00116     }
00117 
00118     MSG_DEBUG("Spherocity value = " << spherocity);
00119 
00120     MSG_DEBUG("Sperocity axis = " << axis);
00121 
00122     _spherocityAxes.push_back(axis);
00123 
00124 
00125   }
00126 }