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