Rivet API documentation

Rivet 4.1.3
ExptResolutionFunctions.hh
1// -*- C++ -*-
2#ifndef RIVET_ExptResolutionFunctions_HH
3#define RIVET_ExptResolutionFunctions_HH
4
5#include "Rivet/Tools/ResolutionFunctions.hh"
6
7#include "YODA/BinnedEstimate.h"
8#include "YODA/Estimate.h"
9#include "YODA/IO.h"
10
11namespace Rivet {
12
14 public:
15
20 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_JET";
21 _h["hist_JERMC16EMTopo"] = refData<YODA::Estimate2D>("hist_JERMC16EMTopo");
22 _h["hist_JERData16EMTopo"] = refData<YODA::Estimate2D>("hist_JERData16EMTopo");
23 }
24
25 // Get resolution based on jet et, abseta.
26 // Return max of MC/Data results.
27 double resolution(const double et, const double abseta) const {
28 const double et_adj = max(min(et, 3000), 17);
29 const double abseta_adj = min(abseta, 4.5);
30
31 return max(_h.at("hist_JERMC16EMTopo").binAt(et_adj, abseta_adj).val(),
32 _h.at("hist_JERData16EMTopo").binAt(et_adj, abseta_adj).val());
33 }
34
37 double resolution(const Jet& j) const override {
38 return resolution(j.Et(), j.abseta());
39 }
40
41 private:
42
43 map<string, YODA::Estimate2D> _h;
44 };
45
47 public:
48
53 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_JET";
54 for (const string s : {"20", "50", "100"}) {
55 const string histname = "hist_jetphi" + s;
56 _h[histname] = refData<YODA::Estimate2D>(histname);
57 }
58 }
59
62 double getRes(const double pt, const double eta, const double phi) const {
63 if (pt < 20 * GeV)
64 return 0.;
65 else if (pt < 50 * GeV)
66 return _h.at("hist_jetphi20").binAt(eta, phi).val();
67 else if (pt < 100 * GeV)
68 return _h.at("hist_jetphi50").binAt(eta, phi).val();
69 return _h.at("hist_jetphi100").binAt(eta, phi).val();
70 }
71
73 double resolution(const Jet& j) const override {
74 return getRes(j.pt(), j.eta(), j.phi(MINUSPI_PLUSPI));
75 }
76
77 private:
78
79 map<string, YODA::Estimate2D> _h;
80 };
81
85 class ATLAS_RUN2_ELECTRON_ET_RES : public ResolutionFunctor<Particle> {
86 public:
87
88 ATLAS_RUN2_ELECTRON_ET_RES() {
89 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_ELECTRON";
90 // TODO: These histograms are small enough (17 bins IIRC) that we could hardcode them if preferred.
91 _h["hist_electronNoise90"] = refData("hist_electronNoise90");
92 _h["hist_electronConst90"] = refData("hist_electronConst90");
93 _h["hist_electronSampling90"] = refData("hist_electronSampling90");
94 }
95
98 double resolution(const double et, const double e, const double abseta) const {
99 // This et range seems almost pointlessly small but hey ho.
100 const double et_adj = max(min(abseta, 50), 5);
101
102 const double rsampling = _h.at("hist_electronSampling90").binAt(abseta).val();
103 const double rnoise = _h.at("hist_electronNoise90").binAt(abseta).val();
104 const double rconst = _h.at("hist_electronConst90").binAt(abseta).val();
105 const double sigma2 = rsampling * rsampling / e + rnoise * rnoise / e / e + rconst * rconst;
106 const double pileupNoiseMeV = sqrt(32.) * (60. + 40. * log(et_adj / 10.) / log(5.));
107 const double pileupSigma2 = (pileupNoiseMeV / 1000. / et_adj) * (pileupNoiseMeV / 1000. / et_adj);
108 return sqrt(sigma2 + pileupSigma2);
109 }
110
112 double resolution(const Particle& e) const override {
113 // TODO: In typical ATLAS fashion, there's a good chance they mean pT
114 return resolution(e.Et(), e.E(), e.abseta());
115 }
116
117 private:
118
119 map<string, YODA::Estimate1D> _h;
120 };
121
127 class ATLAS_RUN2_MUON_PT_RES : public ResolutionFunctor<Particle> {
128 public:
129
130 ATLAS_RUN2_MUON_PT_RES() {
131 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_MUON";
132 for (const string& s : _histosbarrel) {
133 _h[s] = refData<YODA::Estimate2D>("hist_" + s);
134 }
135 for (const string& s : _histosendcap) {
136 _h[s] = refData<YODA::Estimate2D>("hist_" + s);
137 }
138 }
139
145 double resolution(const double pT2, const double eta, const double phi) const {
146 vector<string> whichhistos = abs(eta) < 1.05 ? _histosbarrel : _histosendcap;
147 vector<double> pars = {0., 0., 0., 0., 0.};
148 for (size_t i = 0; i < 5; ++i) {
149 pars[i] = _h.at(whichhistos[i]).binAt(phi, eta).val();
150 }
151 double IDResSq = pars[0] * pars[0] + pars[1] * pars[1] * pT2;
152 double MSResSq = pars[2] * pars[2] / pT2 + pars[3] * pars[3] + pars[4] * pars[4] * pT2;
153 return sqrt(IDResSq * MSResSq / (IDResSq + MSResSq));
154 }
155
157 double resolution(const Particle& mu) const override {
158 return resolution(mu.pt2(), mu.eta(), mu.phi());
159 }
160
161 private:
162
163 map<string, YODA::Estimate2D> _h;
164 std::vector<string> _histosbarrel = {
165 "r1_ID_MC_BARREL", "r2_ID_MC_BARREL", "r0_MS_MC_BARREL", "r1_MS_MC_BARREL", "r2_MS_MC_BARREL",
166 };
167 std::vector<string> _histosendcap = {"r1_ID_MC_ENDCAP", "r2_ID_MC_ENDCAP", "r0_MS_MC_ENDCAP",
168 "r1_MS_MC_ENDCAP", "r2_MS_MC_ENDCAP"};
169 };
170
174 class ATLAS_RUN2_PHOTON_ET_RES : public ResolutionFunctor<Particle> {
175 public:
176
177 ATLAS_RUN2_PHOTON_ET_RES() {
178 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_PHOTON";
179 _h["hist_photonConst90"] = refData<YODA::Estimate1D>("hist_photonConst90");
180 _h["hist_photonNoise90"] = refData<YODA::Estimate1D>("hist_photonNoise90");
181 _h["hist_photonSampling90"] = refData<YODA::Estimate1D>("hist_photonSampling90");
182 }
183
186 double resolution(const double E, const double pt, const double abseta) const {
187 const double rsampling = abseta < 2.4 ? _h.at("hist_photonSampling90").binAt(abseta).val() : 0;
188 const double rnoise = abseta < 2.4 ? _h.at("hist_photonNoise90").binAt(abseta).val() : 0;
189 const double rconst = abseta < 2.4 ? _h.at("hist_photonConst90").binAt(abseta).val() : 0;
190
191 double sigma2 = rsampling * rsampling / E + rnoise * rnoise / (E * E) + rconst * rconst;
192
193 double et = std::min(50., std::max(5., pt)); // constraint 5-50 GeV
194
195 double pileupNoiseMeV = sqrt(32.) * (60. + 40. * log(et / 10.) / log(5.));
196 double pileupSigma2 = (pileupNoiseMeV / 1000. / pt) * (pileupNoiseMeV / 1000. / pt);
197 // not clear why Egamma group uses Et and not E here? (comment left in from SA code)
198 return sqrt(sigma2 + pileupSigma2);
199 }
200
201 double resolution(const Particle& gamma) const override {
202 return resolution(gamma.E(), gamma.pt(), gamma.abseta());
203 }
204
205 private:
206
207 map<string, YODA::Estimate1D> _h;
208 };
209
210
215 class ATLAS_RUN2_TAU_1p0n_PT_RES : public ResolutionFunctor<Jet> {
216 public:
217
218 ATLAS_RUN2_TAU_1p0n_PT_RES() {
219 _refFileName = "ExptResolutionFunctions/ATLAS_RUN2_RES_TAU_1p0n";
220 for (size_t i = 0; i < 5; ++i) {
221 _h[i] = refData<YODA::Estimate1D>("hist_tauRes1p0nBin"s + to_string(i));
222 }
223 }
224
226 double resolution(const double pt, const double abseta) const {
227 const double ptMeV = 1000. * std::min(499., std::max(15., pt)); // only defined for 15-499 GeV
228 const vector<double> etaEdges = {0.0, 0.3, 0.8, 1.3, 1.6};
229 const double res = _h[binIndex(abseta, etaEdges, true)].binAt(ptMeV).val();
230 return res;
231 }
232
233 double resolution(const Jet& hadTau) const override {
234 // TODO: Should we consider an extra check to make sure it is a 1p0n decay?
235 // And maybe a tau-tag check?
236 return resolution(hadTau.pt(), hadTau.abseta());
237 }
238
239 private:
240
242 };
243
244
247
249 class ATLAS_RUN2_MUON_PHI_RES : public ResolutionFunctor<Particle> {
250 public:
251
252 ATLAS_RUN2_MUON_PHI_RES() { }
253 double resolution() const {
254 return 0.001;
255 }
256 double resolution(const Particle& e) const override {
257 return resolution();
258 }
259 };
260
262 class ATLAS_RUN2_ELECTRON_PHI_RES : public ResolutionFunctor<Particle> {
263 public:
264
265 ATLAS_RUN2_ELECTRON_PHI_RES() { }
266 double resolution() const {
267 return 0.004;
268 }
269 double resolution(const Particle& e) const override {
270 return resolution();
271 }
272 };
273
274
276 class ATLAS_RUN2_PHOTON_PHI_RES : public ResolutionFunctor<Particle> {
277 public:
278
279 ATLAS_RUN2_PHOTON_PHI_RES() { }
280 double resolution() const {
281 return 0.004;
282 }
283 double resolution(const Particle& e) const override {
284 return resolution();
285 }
286 };
287
290 class ATLAS_RUN2_TAU_PHI_RES : public ResolutionFunctor<Jet> {
291 public:
292
293 ATLAS_RUN2_TAU_PHI_RES() { }
294 double resolution() const {
295 return 0.01;
296 }
297 double resolution(const Jet& j) const override {
298 return resolution();
299 }
300 };
301
302
303}
304
305#endif
double resolution(const double et, const double e, const double abseta) const
Definition ExptResolutionFunctions.hh:98
double resolution(const Particle &e) const override
Get electron pt/et resolution given a Particle (hopefully an electron).
Definition ExptResolutionFunctions.hh:112
ATLAS_RUN2_EMTOPO_PT_RES()
Definition ExptResolutionFunctions.hh:19
double resolution(const Jet &j) const override
Definition ExptResolutionFunctions.hh:37
double resolution(const Jet &j) const override
Get jet phi resolution given a jet.
Definition ExptResolutionFunctions.hh:73
ATLAS_RUN2_JET_PHI_RES()
Definition ExptResolutionFunctions.hh:52
double getRes(const double pt, const double eta, const double phi) const
Definition ExptResolutionFunctions.hh:62
double resolution(const double pT2, const double eta, const double phi) const
Definition ExptResolutionFunctions.hh:145
double resolution(const Particle &mu) const override
Get muon pt resolution given a Particle.
Definition ExptResolutionFunctions.hh:157
double resolution(const double E, const double pt, const double abseta) const
Definition ExptResolutionFunctions.hh:186
double resolution(const double pt, const double abseta) const
Get hadronic tau pt resolution given pt and abseta.
Definition ExptResolutionFunctions.hh:226
Representation of a clustered jet of particles.
Definition Jet.hh:47
double phi(const PhiMapping mapping=ZERO_2PI) const
Get the directly.
Definition ParticleBase.hh:159
double abseta() const
Get the directly (alias).
Definition ParticleBase.hh:133
double pt2() const
Get the directly.
Definition ParticleBase.hh:90
double pt() const
Get the directly.
Definition ParticleBase.hh:77
double eta() const
Get the directly (alias).
Definition ParticleBase.hh:125
double Et() const
Get the directly.
Definition ParticleBase.hh:103
double E() const
Get the energy directly.
Definition ParticleBase.hh:59
Particle representation, either from a HepMC::GenEvent or reconstructed.
Definition Particle.hh:50
Definition ResolutionFunctions.hh:20
STL class.
const T2 & refData(const string &hname) const
Definition ResolutionFunctions.hh:50
double E(const ParticleBase &p)
Unbound function access to E.
Definition ParticleBaseUtils.hh:829
double eta(const ParticleBase &p)
Unbound function access to eta.
Definition ParticleBaseUtils.hh:839
double abseta(const ParticleBase &p)
Unbound function access to abseta.
Definition ParticleBaseUtils.hh:844
Definition LHCbCommon.hh:9
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, signed_if_mixed_t< N1, N2 > > max(N1 a, N2 b)
Get the maximum of two numbers.
Definition MathUtils.hh:124
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, signed_if_mixed_t< N1, N2 > > min(N1 a, N2 b)
Get the minimum of two numbers.
Definition MathUtils.hh:113
std::enable_if_t< std::is_arithmetic_v< NUM1 > &&std::is_arithmetic_v< NUM2 >, int > binIndex(NUM1 val, std::initializer_list< NUM2 > binedges, bool allow_overflow=false)
Return the bin index of the given value, val, given a vector of bin edges.
Definition MathUtils.hh:503