Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Sphericity.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Projections/Sphericity.hh"
00003 #include "Rivet/Cmp.hh"
00004 #include "Rivet/Tools/Logging.hh"
00005 #include "Rivet/Tools/Utils.hh"
00006 #include "CLHEP/Matrix/Matrix.h"
00007 #include "CLHEP/Matrix/SymMatrix.h"
00008 
00009 using namespace Rivet;
00010 using namespace std;
00011 
00012 
00013 int Sphericity::compare(const Projection& p) const {
00014   const Sphericity & other = dynamic_cast<const Sphericity &>(p);
00015   int fscmp = pcmp(*_fsproj, *other._fsproj);
00016   if (fscmp == 0) {
00017     double rcmp = _regparam - other._regparam;
00018     if (fabs(rcmp) < 1e-3) {
00019       return 0;
00020     } else {
00021       return (rcmp > 0) ? 1 : -1;
00022     }
00023   } else {
00024     return fscmp;
00025   }
00026 }
00027 
00028 
00029 void Sphericity::project(const Event & e) {
00030   Log& log = getLog();
00031 
00032   // Reset parameters
00033   _sphericity = 0;  
00034   _planarity = 7;
00035   _aplanarity = 0;
00036   for (size_t i =0 ; i < 3; ++i) {
00037     _lambdas[i] = 0;
00038   }
00039 
00040   // Get final state.
00041   const FinalState& fs = e.applyProjection(*_fsproj);
00042  
00043   CLHEP::HepMatrix mMom(3,3,0);
00044   double totalMomentum = 0.0;
00045   
00046   // Iterate over all the final state particles.
00047   for (ParticleVector::const_iterator p = fs.particles().begin(); p != fs.particles().end(); ++p) {
00048     
00049     // Get the momentum vector for the final state particle.
00050     LorentzVector lv = p->getMomentum();
00051     
00052     // Build the (regulated) normalising factor.
00053     totalMomentum += pow(lv.vect().mag(), _regparam);
00054     
00055     // Build (regulated) quadratic momentum components.
00056     const double regfactor = pow(lv.vect().mag(), _regparam-2);
00057     log << Log::DEBUG << "Regfactor (r=" << _regparam << ") = " << regfactor << endl;
00058     mMom[0][0] += regfactor * lv.x() * lv.x(); 
00059     mMom[1][1] += regfactor * lv.y() * lv.y();
00060     mMom[2][2] += regfactor * lv.z() * lv.z();
00061     mMom[0][1] += regfactor * lv.y() * lv.x(); 
00062     mMom[1][0] += regfactor * lv.x() * lv.y();
00063     mMom[0][2] += regfactor * lv.z() * lv.x(); 
00064     mMom[2][0] += regfactor * lv.x() * lv.z();
00065     mMom[1][2] += regfactor * lv.z() * lv.y();
00066     mMom[2][1] += regfactor * lv.y() * lv.z(); 
00067   }
00068 
00069   // Normalise to total (regulated) momentum.
00070   mMom /= totalMomentum;
00071 
00072   // Check that the matrix is symmetric.
00073   const bool isSymm = 
00074     fuzzyEquals(mMom[0][1], mMom[1][0]) && 
00075     fuzzyEquals(mMom[0][2], mMom[2][0]) && 
00076     fuzzyEquals(mMom[1][2], mMom[2][1]);
00077   if (!isSymm) {
00078     log << Log::ERROR << "Error: momentum tensor not symmetric (r=" << _regparam << ")" << endl;
00079     log << Log::ERROR << "[0,1] vs. [1,0]: " << mMom[0][1] << ", " << mMom[1][0] << endl;
00080     log << Log::ERROR << "[0,2] vs. [2,0]: " << mMom[0][2] << ", " << mMom[2][0] << endl;
00081     log << Log::ERROR << "[1,2] vs. [2,1]: " << mMom[1][2] << ", " << mMom[2][1] << endl;
00082   }
00083   // If not symmetric, something's wrong (we made sure the error msg appeared first).
00084   assert(isSymm); 
00085 
00086   // Convert to a SymMatrix and diagonalize.
00087   CLHEP::HepSymMatrix symMat;
00088   symMat.assign(mMom);
00089   CLHEP::diagonalize(&symMat);
00090   log << Log::DEBUG << mMom << endl;
00091   log << Log::DEBUG << endl;
00092   
00093   // Put the eigenvalues in the correct order.
00094   for (int i=0; i!=3; ++i){
00095     _lambdas[i] = symMat[i][i]; 
00096   }
00097   const int N = sizeof(_lambdas) / sizeof(double);
00098   sort(_lambdas, _lambdas + N); 
00099   reverse(_lambdas, _lambdas + N); 
00100   log << Log::DEBUG << "Sum of lambdas = " << lambda1() + lambda2() + lambda3() << endl;
00101   
00102   // Construct standard eigenvalue combinations.
00103   _sphericity = 3 / 2.0 * (lambda2() + lambda3());
00104   _aplanarity = 3 / 2.0 *  lambda3();
00105   _planarity  = 2 * (_sphericity - 2 * _aplanarity) / 3.0; 
00106   
00107 }