rivet is hosted by Hepforge, IPPP Durham
FParameter.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Projections/FParameter.hh"
00003 #include "Rivet/Cmp.hh"
00004 #include "Rivet/Tools/Logging.hh"
00005 #include "Rivet/Tools/Utils.hh"
00006 
00007 namespace Rivet {
00008 
00009   FParameter::FParameter(const FinalState& fsp) {
00010     setName("FParameter");
00011     addProjection(fsp, "FS");
00012     clear();
00013   }
00014 
00015 
00016   void FParameter::clear() {
00017     _lambdas = vector<double>(2, 0);
00018   }
00019 
00020 
00021   void FParameter::project(const Event& e) {
00022     const ParticleVector prts = applyProjection<FinalState>(e, "FS").particles();
00023     calc(prts);
00024   }
00025 
00026 
00027   void FParameter::calc(const FinalState& fs) {
00028     calc(fs.particles());
00029   }
00030 
00031   void FParameter::calc(const vector<Particle>& fsparticles) {
00032     vector<Vector3> threeMomenta;
00033     threeMomenta.reserve(fsparticles.size());
00034     foreach (const Particle& p, fsparticles) {
00035       const Vector3 p3 = p.momentum().vector3();
00036       threeMomenta.push_back(p3);
00037     }
00038     _calcFParameter(threeMomenta);
00039   }
00040 
00041   void FParameter::calc(const vector<FourMomentum>& fsmomenta) {
00042     vector<Vector3> threeMomenta;
00043     threeMomenta.reserve(fsmomenta.size());
00044     foreach (const FourMomentum& v, fsmomenta) {
00045       threeMomenta.push_back(v.vector3());
00046     }
00047     _calcFParameter(threeMomenta);
00048   }
00049 
00050   void FParameter::calc(const vector<Vector3>& fsmomenta) {
00051     _calcFParameter(fsmomenta);
00052   }
00053 
00054   // Actually do the calculation
00055   void FParameter::_calcFParameter(const vector<Vector3>& fsmomenta) {
00056 
00057     // Return (with "safe nonsense" sphericity params) if there are no final state particles.
00058     if (fsmomenta.empty()) {
00059       MSG_DEBUG("No particles in final state...");
00060       clear();
00061       return;
00062     }
00063 
00064     // A small iteration over full momenta but set z-coord. to 0.0 to get transverse momenta
00065     vector <Vector3> fsperpmomenta;
00066     foreach (const Vector3& p, fsmomenta) {
00067       fsperpmomenta.push_back(Vector3(p.x(), p.y(), 0.0));
00068     }
00069 
00070     // Iterate over all the final state particles.
00071     Matrix<2> mMom;
00072     MSG_DEBUG("Number of particles = " << fsperpmomenta.size());
00073     foreach (const Vector3& p3, fsperpmomenta) {
00074 
00075       double prefactor = 1.0/mod(p3);
00076 
00077       Matrix<2> mMomPart;
00078       for (size_t i = 0; i < 2; ++i) {
00079         for (size_t j = 0; j < 2; ++j) {
00080           mMomPart.set(i,j, p3[i]*p3[j]);
00081         }
00082       }
00083       mMom += prefactor * mMomPart;
00084     }
00085 
00086     MSG_DEBUG("Linearised transverse momentum tensor = " << mMom);
00087 
00088     // Check that the matrix is symmetric.
00089     const bool isSymm = mMom.isSymm();
00090     if (!isSymm) {
00091       MSG_ERROR("Error: momentum tensor not symmetric:");
00092       MSG_ERROR("[0,1] vs. [1,0]: " << mMom.get(0,1) << ", " << mMom.get(1,0));
00093       MSG_ERROR("[0,2] vs. [2,0]: " << mMom.get(0,2) << ", " << mMom.get(2,0));
00094       MSG_ERROR("[1,2] vs. [2,1]: " << mMom.get(1,2) << ", " << mMom.get(2,1));
00095     }
00096     // If not symmetric, something's wrong (we made sure the error msg appeared first).
00097     assert(isSymm);
00098 
00099     // Diagonalize momentum matrix.
00100     const EigenSystem<2> eigen2 = diagonalize(mMom);
00101     MSG_DEBUG("Diag momentum tensor = " << eigen2.getDiagMatrix());
00102 
00103     // Reset and set eigenvalue parameters.
00104     _lambdas.clear();
00105     const EigenSystem<2>::EigenPairs epairs = eigen2.getEigenPairs();
00106     assert(epairs.size() == 2);
00107     for (size_t i = 0; i < 2; ++i) {
00108       _lambdas.push_back(epairs[i].first);
00109     }
00110 
00111     // Debug output.
00112     MSG_DEBUG("Lambdas = ("
00113              << lambda1() << ", " << lambda2() << ")");
00114     MSG_DEBUG("Sum of lambdas = " << lambda1() + lambda2());
00115   }
00116 }