Sphericity.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Projections/Sphericity.hh" 00003 00004 namespace Rivet { 00005 00006 00007 Sphericity::Sphericity(const FinalState& fsp, double rparam) 00008 : _regparam(rparam) 00009 { 00010 setName("Sphericity"); 00011 addProjection(fsp, "FS"); 00012 clear(); 00013 } 00014 00015 00016 void Sphericity::clear() { 00017 _lambdas = vector<double>(3, 0); 00018 _sphAxes = vector<Vector3>(3, Vector3()); 00019 } 00020 00021 00022 int Sphericity::compare(const Projection& p) const { 00023 PCmp fscmp = mkNamedPCmp(p, "FS"); 00024 if (fscmp != EQUIVALENT) return fscmp; 00025 const Sphericity& other = dynamic_cast<const Sphericity&>(p); 00026 if (fuzzyEquals(_regparam, other._regparam)) return 0; 00027 return cmp(_regparam, other._regparam); 00028 } 00029 00030 00031 void Sphericity::project(const Event& e) { 00032 const Particles prts = applyProjection<FinalState>(e, "FS").particles(); 00033 calc(prts); 00034 } 00035 00036 00037 void Sphericity::calc(const FinalState& fs) { 00038 calc(fs.particles()); 00039 } 00040 00041 void Sphericity::calc(const vector<Particle>& fsparticles) { 00042 vector<Vector3> threeMomenta; 00043 threeMomenta.reserve(fsparticles.size()); 00044 foreach (const Particle& p, fsparticles) { 00045 threeMomenta.push_back( p.momentum().vector3() ); 00046 } 00047 _calcSphericity(threeMomenta); 00048 } 00049 00050 void Sphericity::calc(const vector<FourMomentum>& fsmomenta) { 00051 vector<Vector3> threeMomenta; 00052 threeMomenta.reserve(fsmomenta.size()); 00053 foreach (const FourMomentum& v, fsmomenta) { 00054 threeMomenta.push_back(v.vector3()); 00055 } 00056 _calcSphericity(threeMomenta); 00057 } 00058 00059 void Sphericity::calc(const vector<Vector3>& fsmomenta) { 00060 _calcSphericity(fsmomenta); 00061 } 00062 00063 00064 // Actually do the calculation 00065 void Sphericity::_calcSphericity(const vector<Vector3>& fsmomenta) { 00066 MSG_DEBUG("Calculating sphericity with r = " << _regparam); 00067 00068 // Return (with "safe nonsense" sphericity params) if there are no final state particles. 00069 if (fsmomenta.empty()) { 00070 MSG_DEBUG("No particles in final state..."); 00071 clear(); 00072 return; 00073 } 00074 00075 // Iterate over all the final state particles. 00076 Matrix3 mMom; 00077 double totalMomentum = 0.0; 00078 MSG_DEBUG("Number of particles = " << fsmomenta.size()); 00079 foreach (const Vector3& p3, fsmomenta) { 00080 // Build the (regulated) normalising factor. 00081 totalMomentum += pow(p3.mod(), _regparam); 00082 00083 // Build (regulated) quadratic momentum components. 00084 const double regfactor = pow(p3.mod(), _regparam-2); 00085 if (!fuzzyEquals(regfactor, 1.0)) { 00086 MSG_TRACE("Regfactor (r=" << _regparam << ") = " << regfactor); 00087 } 00088 00089 Matrix3 mMomPart; 00090 for (size_t i = 0; i < 3; ++i) { 00091 for (size_t j = 0; j < 3; ++j) { 00092 mMomPart.set(i,j, p3[i]*p3[j]); 00093 } 00094 } 00095 mMom += regfactor * mMomPart; 00096 } 00097 00098 // Normalise to total (regulated) momentum. 00099 mMom /= totalMomentum; 00100 MSG_DEBUG("Momentum tensor = " << "\n" << mMom); 00101 00102 // Check that the matrix is symmetric. 00103 const bool isSymm = mMom.isSymm(); 00104 if (!isSymm) { 00105 MSG_ERROR("Error: momentum tensor not symmetric (r=" << _regparam << ")"); 00106 MSG_ERROR("[0,1] vs. [1,0]: " << mMom.get(0,1) << ", " << mMom.get(1,0)); 00107 MSG_ERROR("[0,2] vs. [2,0]: " << mMom.get(0,2) << ", " << mMom.get(2,0)); 00108 MSG_ERROR("[1,2] vs. [2,1]: " << mMom.get(1,2) << ", " << mMom.get(2,1)); 00109 } 00110 // If not symmetric, something's wrong (we made sure the error msg appeared first). 00111 assert(isSymm); 00112 00113 // Diagonalize momentum matrix. 00114 const EigenSystem<3> eigen3 = diagonalize(mMom); 00115 MSG_DEBUG("Diag momentum tensor = " << "\n" << eigen3.getDiagMatrix()); 00116 00117 // Reset and set eigenvalue/vector parameters. 00118 _lambdas.clear(); 00119 _sphAxes.clear(); 00120 const EigenSystem<3>::EigenPairs epairs = eigen3.getEigenPairs(); 00121 assert(epairs.size() == 3); 00122 for (size_t i = 0; i < 3; ++i) { 00123 _lambdas.push_back(epairs[i].first); 00124 _sphAxes.push_back(Vector3(epairs[i].second)); 00125 } 00126 00127 // Debug output. 00128 MSG_DEBUG("Lambdas = (" 00129 << lambda1() << ", " << lambda2() << ", " << lambda3() << ")"); 00130 MSG_DEBUG("Sum of lambdas = " << lambda1() + lambda2() + lambda3()); 00131 MSG_DEBUG("Vectors = " 00132 << sphericityAxis() << ", " 00133 << sphericityMajorAxis() << ", " 00134 << sphericityMinorAxis() << ")"); 00135 } 00136 00137 } Generated on Thu Feb 6 2014 17:38:46 for The Rivet MC analysis system by ![]() |