SmearedParticles.hh
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #ifndef RIVET_SmearedParticles_HH 00003 #define RIVET_SmearedParticles_HH 00004 00005 #include "Rivet/Particle.hh" 00006 #include "Rivet/Projection.hh" 00007 #include "Rivet/Projections/ParticleFinder.hh" 00008 #include "Rivet/Tools/SmearingFunctions.hh" 00009 #include <functional> 00010 00011 namespace Rivet { 00012 00013 00014 /// Wrapper projection for smearing {@link Jet}s with detector resolutions and efficiencies 00015 class SmearedParticles : public ParticleFinder { 00016 public: 00017 00018 /// @name Constructors etc. 00019 //@{ 00020 00021 /// @brief Constructor with efficiency and smearing function args 00022 template <typename P2DFN> 00023 SmearedParticles(const ParticleFinder& pf, 00024 const P2DFN& effFn, 00025 const Cut& c=Cuts::open()) 00026 : SmearedParticles(pf, effFn, PARTICLE_SMEAR_IDENTITY, c) 00027 { } 00028 00029 00030 /// @brief Constructor with efficiency and smearing function args 00031 template <typename P2DFN, typename P2PFN> 00032 SmearedParticles(const ParticleFinder& pf, 00033 const P2DFN& effFn, const P2PFN& smearFn, 00034 const Cut& c=Cuts::open()) 00035 : ParticleFinder(c), 00036 _effFn(effFn), _smearFn(smearFn) 00037 { 00038 setName("SmearedParticles"); 00039 addProjection(pf, "TruthParticles"); 00040 } 00041 00042 00043 /// Clone on the heap. 00044 DEFAULT_RIVET_PROJ_CLONE(SmearedParticles); 00045 00046 //@} 00047 00048 00049 /// Compare to another SmearedParticles 00050 int compare(const Projection& p) const { 00051 const SmearedParticles& other = dynamic_cast<const SmearedParticles&>(p); 00052 if (get_address(_effFn) == 0) return UNDEFINED; 00053 if (get_address(_smearFn) == 0) return UNDEFINED; 00054 MSG_TRACE("Eff hashes = " << get_address(_effFn) << "," << get_address(other._effFn) << "; " << 00055 "smear hashes = " << get_address(_smearFn) << "," << get_address(other._smearFn)); 00056 return mkPCmp(other, "TruthParticles") || 00057 cmp(get_address(_effFn), get_address(other._effFn)) || 00058 cmp(get_address(_smearFn), get_address(other._smearFn)); 00059 } 00060 00061 00062 /// Perform the particle finding & smearing calculation 00063 void project(const Event& e) { 00064 // Copying and filtering 00065 const Particles& truthparticles = apply<ParticleFinder>(e, "TruthParticles").particlesByPt(); 00066 _theParticles.clear(); _theParticles.reserve(truthparticles.size()); 00067 for (const Particle& p : truthparticles) { 00068 const double peff = _effFn ? _effFn(p) : 1; 00069 MSG_DEBUG("Efficiency of particle with pid=" << p.pid() 00070 << ", mom=" << p.mom()/GeV << " GeV, " 00071 << "pT=" << p.pT()/GeV << ", eta=" << p.eta() 00072 << " : " << 100*peff << "%"); 00073 if (peff <= 0) continue; //< no need to roll expensive dice (and we deal with -ve probabilities, just in case) 00074 if (peff < 1 && rand01() > peff) continue; //< roll dice (and deal with >1 probabilities, just in case) 00075 _theParticles.push_back(_smearFn ? _smearFn(p) : p); //< smearing 00076 } 00077 } 00078 00079 00080 /// Reset the projection. Smearing functions will be unchanged. 00081 void reset() { _theParticles.clear(); } 00082 00083 00084 private: 00085 00086 /// Stored efficiency function 00087 std::function<double(const Particle&)> _effFn; 00088 00089 /// Stored smearing function 00090 std::function<Particle(const Particle&)> _smearFn; 00091 00092 }; 00093 00094 00095 } 00096 00097 #endif Generated on Tue Dec 13 2016 16:32:40 for The Rivet MC analysis system by ![]() |