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