File indexing completed on 2025-05-12 09:05:03
0001
0002 #ifndef RIVET_SmearedJets_HH
0003 #define RIVET_SmearedJets_HH
0004
0005 #include "Rivet/Jet.hh"
0006 #include "Rivet/Particle.hh"
0007 #include "Rivet/Projection.hh"
0008 #include "Rivet/Projections/JetFinder.hh"
0009 #include "Rivet/Tools/SmearingFunctions.hh"
0010 #include <functional>
0011
0012 namespace Rivet {
0013
0014
0015
0016
0017
0018
0019 class SmearedJets : public JetFinder {
0020 public:
0021
0022
0023
0024
0025
0026
0027
0028 SmearedJets(const JetFinder& ja,
0029 const JetSmearFn& smearFn,
0030 const JetEffFn& bTagEffFn=JET_BTAG_PERFECT,
0031 const JetEffFn& cTagEffFn=JET_CTAG_PERFECT)
0032 : SmearedJets(ja, bTagEffFn, cTagEffFn, smearFn)
0033 { }
0034
0035
0036
0037
0038
0039
0040 template <typename... Args,
0041 typename = std::enable_if_t< allArgumentsOf<JetEffSmearFn, Args...>::value >>
0042 SmearedJets(const JetFinder& ja, const JetEffFn& bTagEffFn, const JetEffFn& cTagEffFn, Args&& ... effSmearFns)
0043 : _detFns({JetEffSmearFn(std::forward<Args>(effSmearFns))...}), _bTagEffFn(bTagEffFn), _cTagEffFn(cTagEffFn)
0044 {
0045 setName("SmearedJets");
0046 declare(ja, "TruthJets");
0047 }
0048
0049
0050
0051
0052
0053
0054
0055 RIVET_DEFAULT_PROJ_CLONE(SmearedJets);
0056
0057
0058
0059
0060 using Projection::operator =;
0061
0062
0063
0064 CmpState compare(const Projection& p) const {
0065
0066 const CmpState teq = mkPCmp(p, "TruthJets");
0067 if (teq != CmpState::EQ) return teq;
0068
0069
0070 const SmearedJets& other = dynamic_cast<const SmearedJets&>(p);
0071 const CmpState nfeq = cmp(_detFns.size(), other._detFns.size());
0072 if (nfeq != CmpState::EQ) return nfeq;
0073 for (size_t i = 0; i < _detFns.size(); ++i) {
0074 const CmpState feq = _detFns[i].cmp(other._detFns[i]);
0075 if (feq != CmpState::EQ) return feq;
0076 }
0077 return Rivet::cmp(get_address(_bTagEffFn), get_address(other._bTagEffFn)) ||
0078 Rivet::cmp(get_address(_cTagEffFn), get_address(other._cTagEffFn));
0079 }
0080
0081
0082
0083 void project(const Event& e) {
0084
0085 const Jets& truthjets = apply<JetFinder>(e, "TruthJets").jetsByPt();
0086 _recojets.clear(); _recojets.reserve(truthjets.size());
0087
0088 for (const Jet& j : truthjets) {
0089 Jet jdet = j;
0090 bool keep = true;
0091 MSG_DEBUG("Truth jet: " << "mom=" << jdet.mom()/GeV << " GeV, pT=" << jdet.pT()/GeV << ", eta=" << jdet.eta());
0092 for (const JetEffSmearFn& fn : _detFns) {
0093 double jeff = -1;
0094 std::tie(jdet, jeff) = fn(jdet);
0095
0096 if (jdet.particles().empty() && !j.particles().empty()) jdet.particles() = j.particles();
0097 if (jdet.tags().empty() && !j.tags().empty()) jdet.tags() = j.tags();
0098 MSG_DEBUG(" ->" << "mom=" << jdet.mom()/GeV << " GeV, pT=" << jdet.pT()/GeV << ", eta=" << jdet.eta());
0099
0100
0101
0102
0103
0104 if (jeff <= 0) { keep = false; break; }
0105 if (jeff < 1 && rand01() > jeff) { keep = false; break; }
0106 }
0107 if (keep) _recojets.push_back(jdet);
0108 }
0109
0110 for (Jet& j : _recojets) {
0111
0112 const double beff = _bTagEffFn ? _bTagEffFn(j) : j.bTagged();
0113 const bool btag = beff == 1 || (beff != 0 && rand01() < beff);
0114
0115 if (!btag && j.bTagged()) j.tags().erase(std::remove_if(j.tags().begin(), j.tags().end(), hasBottom), j.tags().end());
0116 if (btag && !j.bTagged()) j.tags().push_back(Particle(PID::BQUARK, j.mom()));
0117
0118 const double ceff = _cTagEffFn ? _cTagEffFn(j) : j.cTagged();
0119 const bool ctag = ceff == 1 || (ceff != 0 && rand01() < beff);
0120
0121 if (!ctag && j.cTagged()) j.tags().erase(std::remove_if(j.tags().begin(), j.tags().end(), hasCharm), j.tags().end());
0122 if (ctag && !j.cTagged()) j.tags().push_back(Particle(PID::CQUARK, j.mom()));
0123 }
0124 }
0125
0126
0127
0128 Jets _jets() const { return _recojets; }
0129
0130
0131 const Jets truthJets() const {
0132 return getProjection<JetFinder>("TruthJets").jetsByPt();
0133 }
0134
0135
0136 void reset() { _recojets.clear(); }
0137
0138
0139 protected:
0140
0141
0142 Jets _recojets;
0143
0144
0145 vector<JetEffSmearFn> _detFns;
0146
0147
0148 JetEffFn _bTagEffFn, _cTagEffFn;
0149
0150 };
0151
0152
0153 }
0154
0155 #endif