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       getLog() << Log::DEBUG << "No particles in final state..." << endl;
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     getLog() << Log::DEBUG << "Number of particles = " << fsperpmomenta.size() << endl;
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     getLog() << Log::DEBUG << "Linearised transverse momentum tensor = " << endl << mMom << endl;
00087 
00088     // Check that the matrix is symmetric.
00089     const bool isSymm = mMom.isSymm();
00090     if (!isSymm) {
00091       getLog() << Log::ERROR << "Error: momentum tensor not symmetric:" << endl;
00092       getLog() << Log::ERROR << "[0,1] vs. [1,0]: " << mMom.get(0,1) << ", " << mMom.get(1,0) << endl;
00093       getLog() << Log::ERROR << "[0,2] vs. [2,0]: " << mMom.get(0,2) << ", " << mMom.get(2,0) << endl;
00094       getLog() << Log::ERROR << "[1,2] vs. [2,1]: " << mMom.get(1,2) << ", " << mMom.get(2,1) << endl;
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     getLog() << Log::DEBUG << "Diag momentum tensor = " << endl << eigen2.getDiagMatrix() << endl;
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     getLog() << Log::DEBUG << "Lambdas = ("
00113              << lambda1() << ", " << lambda2() << ")" << endl;
00114     getLog() << Log::DEBUG << "Sum of lambdas = " << lambda1() + lambda2() << endl;
00115   }
00116 }