File indexing completed on 2026-05-19 08:22:12
0001
0002 #ifndef RIVET_ExptSmearingFunctions_HH
0003 #define RIVET_ExptSmearingFunctions_HH
0004
0005 #include "Rivet/Tools/MomentumSmearingFunctions.hh"
0006 #include "Rivet/Tools/ParticleSmearingFunctions.hh"
0007 #include "Rivet/Tools/JetSmearingFunctions.hh"
0008
0009 namespace Rivet {
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 inline double ELECTRON_RECOEFF_ATLAS_RUN1(const Particle& e) {
0040 if (e.abspid() != PID::ELECTRON) return 0;
0041 if (e.abseta() > 2.5) return 0;
0042 if (e.pT() < 10*GeV) return 0;
0043 return (e.abseta() < 1.5) ? 0.95 : 0.85;
0044 }
0045
0046
0047
0048
0049 inline double ELECTRON_RECOEFF_ATLAS_RUN2(const Particle& e) {
0050 if (e.abspid() != PID::ELECTRON) return 0;
0051 const double et = e.Et();
0052 if (e.abseta() > 2.5 || e.Et() < 2*GeV) return 0;
0053 if (et > 25*GeV) return 0.97;
0054 if (et > 10*GeV) return 0.92 + (et/GeV-10)/15.*0.05;
0055 if (et > 6*GeV) return 0.85 + (et/GeV-6)/4.*0.07;
0056 if (et > 5*GeV) return 0.70 + (et/GeV-5)/1.*0.15;
0057 if (et > 2*GeV) return 0.00 + (et/GeV-2)/3.*0.70;
0058 return 0;
0059 }
0060
0061
0062
0063
0064
0065
0066
0067 inline double ELECTRON_EFF_ATLAS_RUN2_LOOSE(const Particle& e) {
0068 if (e.abspid() != PID::ELECTRON) return 0;
0069
0070
0071 const static vector<double> edges_eta = { 0.0, 0.1, 0.8, 1.37, 1.52, 2.01, 2.37, 2.47 };
0072 const static vector<double> effs_eta = { 0.950, 0.965, 0.955, 0.885, 0.950, 0.935, 0.90 };
0073
0074 const static vector<double> edges_et = { 0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 80 };
0075 const static vector<double> effs_et = { 0.0, 0.90, 0.91, 0.92, 0.94, 0.95, 0.955, 0.965, 0.97, 0.98, 0.98 };
0076
0077 if (e.abseta() > 2.47) return 0.0;
0078
0079 const int i_eta = binIndex(e.abseta(), edges_eta);
0080 const int i_et = binIndex(e.Et()/GeV, edges_et, true);
0081 const double eff = effs_et[i_et] * effs_eta[i_eta] / 0.95;
0082 return min(eff, 1.0) * ELECTRON_RECOEFF_ATLAS_RUN2(e);
0083 }
0084
0085
0086 inline double ELECTRON_EFF_ATLAS_RUN1_LOOSE(const Particle& e) {
0087 return ELECTRON_EFF_ATLAS_RUN2_LOOSE(e);
0088 }
0089
0090
0091
0092 inline double ELECTRON_EFF_ATLAS_RUN1_MEDIUM(const Particle& e) {
0093 if (e.abspid() != PID::ELECTRON) return 0;
0094
0095 const static vector<double> eta_edges_10 = {0.000, 0.049, 0.454, 1.107, 1.46, 1.790, 2.277, 2.500};
0096 const static vector<double> eta_vals_10 = {0.730, 0.757, 0.780, 0.771, 0.77, 0.777, 0.778};
0097
0098 const static vector<double> eta_edges_15 = {0.000, 0.053, 0.456, 1.102, 1.463, 1.783, 2.263, 2.500};
0099 const static vector<double> eta_vals_15 = {0.780, 0.800, 0.819, 0.759, 0.749, 0.813, 0.829};
0100
0101 const static vector<double> eta_edges_20 = {0.000, 0.065, 0.362, 0.719, 0.980, 1.289, 1.455, 1.681, 1.942, 2.239, 2.452, 2.500};
0102 const static vector<double> eta_vals_20 = {0.794, 0.806, 0.816, 0.806, 0.797, 0.774, 0.764, 0.788, 0.793, 0.806, 0.825};
0103
0104 const static vector<double> eta_edges_25 = {0.000, 0.077, 0.338, 0.742, 1.004, 1.265, 1.467, 1.692, 1.940, 2.227, 2.452, 2.500};
0105 const static vector<double> eta_vals_25 = {0.833, 0.843, 0.853, 0.845, 0.839, 0.804, 0.790, 0.825, 0.830, 0.833, 0.839};
0106
0107 const static vector<double> eta_edges_30 = {0.000, 0.077, 0.350, 0.707, 0.980, 1.289, 1.479, 1.681, 1.942, 2.239, 2.441, 2.500};
0108 const static vector<double> eta_vals_30 = {0.863, 0.872, 0.881, 0.874, 0.870, 0.824, 0.808, 0.847, 0.845, 0.840, 0.842};
0109
0110 const static vector<double> eta_edges_35 = {0.000, 0.058, 0.344, 0.700, 1.009, 1.270, 1.458, 1.685, 1.935, 2.231, 2.468, 2.500};
0111 const static vector<double> eta_vals_35 = {0.878, 0.889, 0.901, 0.895, 0.893, 0.849, 0.835, 0.868, 0.863, 0.845, 0.832};
0112
0113 const static vector<double> eta_edges_40 = {0.000, 0.047, 0.355, 0.699, 0.983, 1.280, 1.446, 1.694, 1.943, 2.227, 2.441, 2.500};
0114 const static vector<double> eta_vals_40 = {0.894, 0.901, 0.909, 0.905, 0.904, 0.875, 0.868, 0.889, 0.876, 0.848, 0.827};
0115
0116 const static vector<double> eta_edges_45 = {0.000, 0.058, 0.356, 0.712, 0.997, 1.282, 1.459, 1.686, 1.935, 2.220, 2.444, 2.500};
0117 const static vector<double> eta_vals_45 = {0.900, 0.911, 0.923, 0.918, 0.917, 0.897, 0.891, 0.904, 0.894, 0.843, 0.796};
0118
0119 const static vector<double> eta_edges_50 = {0.000, 0.059, 0.355, 0.711, 0.983, 1.280, 1.469, 1.682, 1.919, 2.227, 2.441, 2.500};
0120 const static vector<double> eta_vals_50 = {0.903, 0.913, 0.923, 0.922, 0.923, 0.903, 0.898, 0.908, 0.895, 0.831, 0.774};
0121
0122 const static vector<double> eta_edges_60 = {0.000, 0.053, 0.351, 0.720, 1.006, 1.291, 1.469, 1.696, 1.946, 2.243, 2.455, 2.500};
0123 const static vector<double> eta_vals_60 = {0.903, 0.917, 0.928, 0.924, 0.927, 0.915, 0.911, 0.915, 0.899, 0.827, 0.760};
0124
0125 const static vector<double> eta_edges_80 = {0.000, 0.053, 0.351, 0.720, 0.994, 1.292, 1.482, 1.708, 1.934, 2.220, 2.458, 2.500};
0126 const static vector<double> eta_vals_80 = {0.936, 0.942, 0.952, 0.956, 0.956, 0.934, 0.931, 0.944, 0.933, 0.940, 0.948};
0127
0128 const static vector<double> et_edges = { 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 80 };
0129 const static vector< vector<double> > et_eta_edges = { eta_edges_10, eta_edges_15, eta_edges_20, eta_edges_25, eta_edges_30, eta_edges_35, eta_edges_40, eta_edges_45, eta_edges_50, eta_edges_60, eta_edges_80 };
0130 const static vector< vector<double> > et_eta_vals = { eta_vals_10, eta_vals_15, eta_vals_20, eta_vals_25, eta_vals_30, eta_vals_35, eta_vals_40, eta_vals_45, eta_vals_50, eta_vals_60, eta_vals_80 };
0131
0132 if (e.abseta() > 2.5 || e.Et() < 10*GeV) return 0.0;
0133 const int i_et = binIndex(e.Et()/GeV, et_edges, true);
0134 const int i_eta = binIndex(e.abseta(), et_eta_edges[i_et]);
0135 return et_eta_vals[i_et][i_eta] * ELECTRON_RECOEFF_ATLAS_RUN1(e);
0136 }
0137
0138
0139
0140
0141 inline double ELECTRON_EFF_ATLAS_RUN2_MEDIUM(const Particle& e) {
0142 if (e.abspid() != PID::ELECTRON) return 0;
0143 return 1.01 * ELECTRON_EFF_ATLAS_RUN1_MEDIUM(e);
0144 }
0145
0146
0147
0148 inline double ELECTRON_EFF_ATLAS_RUN1_TIGHT(const Particle& e) {
0149 if (e.abspid() != PID::ELECTRON) return 0;
0150
0151 const static vector<double> eta_edges_10 = {0.000, 0.049, 0.459, 1.100, 1.461, 1.789, 2.270, 2.500};
0152 const static vector<double> eta_vals_10 = {0.581, 0.632, 0.668, 0.558, 0.548, 0.662, 0.690};
0153
0154 const static vector<double> eta_edges_15 = {0.000, 0.053, 0.450, 1.096, 1.463, 1.783, 2.269, 2.500};
0155 const static vector<double> eta_vals_15 = {0.630, 0.678, 0.714, 0.633, 0.616, 0.700, 0.733};
0156
0157 const static vector<double> eta_edges_20 = {0.000, 0.065, 0.362, 0.719, 0.992, 1.277, 1.479, 1.692, 1.930, 2.227, 2.464, 2.500};
0158 const static vector<double> eta_vals_20 = {0.653, 0.695, 0.735, 0.714, 0.688, 0.635, 0.625, 0.655, 0.680, 0.691, 0.674};
0159
0160 const static vector<double> eta_edges_25 = {0.000, 0.077, 0.362, 0.719, 0.992, 1.300, 1.479, 1.692, 1.942, 2.227, 2.464, 2.500};
0161 const static vector<double> eta_vals_25 = {0.692, 0.732, 0.768, 0.750, 0.726, 0.677, 0.667, 0.692, 0.710, 0.706, 0.679};
0162
0163 const static vector<double> eta_edges_30 = {0.000, 0.053, 0.362, 0.719, 1.004, 1.277, 1.467, 1.681, 1.954, 2.239, 2.452, 2.500};
0164 const static vector<double> eta_vals_30 = {0.724, 0.763, 0.804, 0.789, 0.762, 0.702, 0.690, 0.720, 0.731, 0.714, 0.681};
0165
0166 const static vector<double> eta_edges_35 = {0.000, 0.044, 0.342, 0.711, 0.971, 1.280, 1.456, 1.683, 1.944, 2.218, 2.442, 2.500};
0167 const static vector<double> eta_vals_35 = {0.736, 0.778, 0.824, 0.811, 0.784, 0.730, 0.718, 0.739, 0.743, 0.718, 0.678};
0168
0169 const static vector<double> eta_edges_40 = {0.000, 0.047, 0.355, 0.699, 0.983, 1.268, 1.457, 1.671, 1.931, 2.204, 2.453, 2.500};
0170 const static vector<double> eta_vals_40 = {0.741, 0.774, 0.823, 0.823, 0.802, 0.764, 0.756, 0.771, 0.771, 0.734, 0.684};
0171
0172 const static vector<double> eta_edges_45 = {0.000, 0.056, 0.354, 0.711, 0.984, 1.280, 1.458, 1.684, 1.945, 2.207, 2.442, 2.500};
0173 const static vector<double> eta_vals_45 = {0.758, 0.792, 0.841, 0.841, 0.823, 0.792, 0.786, 0.796, 0.794, 0.734, 0.663};
0174
0175 const static vector<double> eta_edges_50 = {0.000, 0.059, 0.355, 0.699, 0.983, 1.268, 1.446, 1.682, 1.943, 2.216, 2.453, 2.500};
0176 const static vector<double> eta_vals_50 = {0.771, 0.806, 0.855, 0.858, 0.843, 0.810, 0.800, 0.808, 0.802, 0.730, 0.653};
0177
0178 const static vector<double> eta_edges_60 = {0.000, 0.050, 0.350, 0.707, 0.981, 1.278, 1.468, 1.694, 1.944, 2.242, 2.453, 2.500};
0179 const static vector<double> eta_vals_60 = {0.773, 0.816, 0.866, 0.865, 0.853, 0.820, 0.812, 0.817, 0.804, 0.726, 0.645};
0180
0181 const static vector<double> eta_edges_80 = {0.000, 0.051, 0.374, 0.720, 0.981, 1.279, 1.468, 1.707, 1.945, 2.207, 2.457, 2.500};
0182 const static vector<double> eta_vals_80 = {0.819, 0.855, 0.899, 0.906, 0.900, 0.869, 0.865, 0.873, 0.869, 0.868, 0.859};
0183
0184 const static vector<double> et_edges = { 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 80 };
0185 const static vector< vector<double> > et_eta_edges = { eta_edges_10, eta_edges_15, eta_edges_20, eta_edges_25, eta_edges_30, eta_edges_35, eta_edges_40, eta_edges_45, eta_edges_50, eta_edges_60, eta_edges_80 };
0186 const static vector< vector<double> > et_eta_vals = { eta_vals_10, eta_vals_15, eta_vals_20, eta_vals_25, eta_vals_30, eta_vals_35, eta_vals_40, eta_vals_45, eta_vals_50, eta_vals_60, eta_vals_80 };
0187
0188 if (e.abseta() > 2.5 || e.Et() < 10*GeV) return 0.0;
0189 const int i_et = binIndex(e.Et()/GeV, et_edges, true);
0190 const int i_eta = binIndex(e.abseta(), et_eta_edges[i_et]);
0191 return et_eta_vals[i_et][i_eta] * ELECTRON_RECOEFF_ATLAS_RUN1(e);
0192 }
0193
0194
0195
0196
0197 inline double ELECTRON_EFF_ATLAS_RUN2_TIGHT(const Particle& e) {
0198 if (e.abspid() != PID::ELECTRON) return 0;
0199 const static vector<double> et_edges = { 20, 25, 30, 35, 40, 45, 50, 60, 80 };
0200 const static vector<double> et_effs = { 0.785, 0.805, 0.820, 0.830, 0.840, 0.850, 0.875, 0.910, 0.910 };
0201 const static vector<double> eta_edges = {0.000, 0.051, 0.374, 0.720, 0.981, 1.279, 1.468, 1.707, 1.945, 2.207, 2.457, 2.500};
0202 const static vector<double> eta_refs = {0.819, 0.855, 0.899, 0.906, 0.900, 0.869, 0.865, 0.873, 0.869, 0.868, 0.859};
0203 if (e.abseta() > 2.5 || e.Et() < 20*GeV) return 0.0;
0204 const int i_et = binIndex(e.Et()/GeV, et_edges, true);
0205 const int i_eta = binIndex(e.abseta(), eta_edges);
0206 const double eff_et = et_effs[i_et];
0207
0208 const double eff = eff_et * (eta_refs[i_eta]/0.85) * ELECTRON_RECOEFF_ATLAS_RUN2(e);
0209
0210 return eff;
0211 }
0212
0213
0214
0215
0216 inline Particle ELECTRON_SMEAR_ATLAS_RUN1(const Particle& e) {
0217 static const vector<double> edges_eta = {0., 2.5, 3.};
0218 static const vector<double> edges_pt = {0., 0.1, 25.};
0219 static const vector<double> e2s = {0.000, 0.015, 0.005,
0220 0.005, 0.005, 0.005,
0221 0.107, 0.107, 0.107};
0222 static const vector<double> es = {0.00, 0.00, 0.05,
0223 0.05, 0.05, 0.05,
0224 2.08, 2.08, 2.08};
0225 static const vector<double> cs = {0.00, 0.00, 0.25,
0226 0.25, 0.25, 0.25,
0227 0.00, 0.00, 0.00};
0228
0229 const int i_eta = binIndex(e.abseta(), edges_eta, true);
0230 const int i_pt = binIndex(e.pT()/GeV, edges_pt, true);
0231 const int i = i_eta*edges_pt.size() + i_pt;
0232
0233
0234 const double c1 = sqr(e2s[i]), c2 = sqr(es[i]), c3 = sqr(cs[i]);
0235 const double resolution = sqrt(c1*e.E2() + c2*e.E() + c3) * GeV;
0236
0237
0238
0239
0240
0241 return Particle(e.pid(), P4_SMEAR_E_GAUSS(e, resolution));
0242 }
0243
0244
0245
0246
0247
0248 inline Particle ELECTRON_SMEAR_ATLAS_RUN2(const Particle& e) {
0249 return ELECTRON_SMEAR_ATLAS_RUN1(e);
0250 }
0251
0252
0253
0254
0255
0256
0257
0258 inline double ELECTRON_EFF_CMS_RUN1(const Particle& e) {
0259 if (e.abspid() != PID::ELECTRON) return 0;
0260 if (e.abseta() > 2.5) return 0;
0261 if (e.pT() < 10*GeV) return 0;
0262 return (e.abseta() < 1.5) ? 0.95 : 0.85;
0263 }
0264
0265
0266 inline double ELECTRON_EFF_CMS_RUN1_LOOSE(const Particle& e) { return ELECTRON_EFF_CMS_RUN1(e); }
0267
0268
0269 inline double ELECTRON_EFF_CMS_RUN1_MEDIUM(const Particle& e) { return ELECTRON_EFF_CMS_RUN1(e); }
0270
0271
0272 inline double ELECTRON_EFF_CMS_RUN1_TIGHT(const Particle& e) { return ELECTRON_EFF_CMS_RUN1(e); }
0273
0274
0275
0276
0277
0278 inline double ELECTRON_EFF_CMS_RUN2(const Particle& e) {
0279 if (e.abspid() != PID::ELECTRON) return 0;
0280 return ELECTRON_EFF_CMS_RUN1(e);
0281 }
0282
0283
0284 inline double ELECTRON_EFF_CMS_RUN2_LOOSE(const Particle& e) { return ELECTRON_EFF_CMS_RUN2(e); }
0285
0286
0287 inline double ELECTRON_EFF_CMS_RUN2_MEDIUM(const Particle& e) { return ELECTRON_EFF_CMS_RUN2(e); }
0288
0289
0290 inline double ELECTRON_EFF_CMS_RUN2_TIGHT(const Particle& e) { return ELECTRON_EFF_CMS_RUN2(e); }
0291
0292
0293
0294
0295
0296
0297
0298
0299 inline Particle ELECTRON_SMEAR_CMS_RUN1(const Particle& e) {
0300
0301 double resolution = 0;
0302 const double abseta = e.abseta();
0303 if (e.pT() > 0.1*GeV && abseta < 2.5) {
0304 if (abseta < 0.5) {
0305 resolution = add_quad(0.06, 1.3e-3 * e.pT()/GeV) * GeV;
0306 } else if (abseta < 1.5) {
0307 resolution = add_quad(0.10, 1.7e-3 * e.pT()/GeV) * GeV;
0308 } else {
0309 resolution = add_quad(0.25, 3.1e-3 * e.pT()/GeV) * GeV;
0310 }
0311 }
0312
0313
0314
0315
0316
0317 return Particle(e.pid(), P4_SMEAR_E_GAUSS(e, resolution));
0318 }
0319
0320
0321
0322
0323 inline Particle ELECTRON_SMEAR_CMS_RUN2(const Particle& e) {
0324 return ELECTRON_SMEAR_CMS_RUN1(e);
0325 }
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 inline double PHOTON_EFF_ATLAS_RUN1(const Particle& y) {
0338 if (y.abspid() != PID::PHOTON) return 0;
0339
0340 if (y.pT() < 10*GeV) return 0;
0341 if (inRange(y.abseta(), 1.37, 1.52) || y.abseta() > 2.37) return 0;
0342
0343 static const vector<double> edges_eta = {0., 0.6, 1.37, 1.52, 1.81, 2.37};
0344 static const vector<double> edges_pt = {10., 15., 20., 25., 30., 35., 40., 45.,
0345 50., 60., 80., 100., 125., 150., 175., 250.};
0346 static const vector<double> effs = {0.53, 0.65, 0.73, 0.83, 0.86, 0.93, 0.94, 0.96,
0347 0.97, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98,
0348 0.45, 0.57, 0.67, 0.74, 0.84, 0.87, 0.93, 0.94,
0349 0.95, 0.96, 0.97, 0.98, 0.98, 0.99, 0.99, 0.99,
0350 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
0351 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
0352 0.48, 0.56, 0.68, 0.76, 0.86, 0.90, 0.93, 0.95,
0353 0.96, 0.97, 0.98, 0.99, 0.99, 1.00, 1.00, 1.00,
0354 0.50, 0.61, 0.74, 0.82, 0.88, 0.92, 0.94, 0.95,
0355 0.96, 0.97, 0.98, 0.98, 0.98, 0.98, 0.99, 0.99};
0356
0357 const int i_eta = binIndex(y.abseta(), edges_eta);
0358 const int i_pt = binIndex(y.pT()/GeV, edges_pt, true);
0359 const int i = i_eta*edges_pt.size() + i_pt;
0360 const double eff = effs[i];
0361 return eff;
0362 }
0363
0364
0365 inline double PHOTON_EFF_ATLAS_RUN1_LOOSE(const Particle& y) { return PHOTON_EFF_ATLAS_RUN1(y); }
0366
0367
0368 inline double PHOTON_EFF_ATLAS_RUN1_MEDIUM(const Particle& y) { return PHOTON_EFF_ATLAS_RUN1(y); }
0369
0370
0371 inline double PHOTON_EFF_ATLAS_RUN1_TIGHT(const Particle& y) { return PHOTON_EFF_ATLAS_RUN1(y); }
0372
0373
0374
0375
0376
0377 inline double PHOTON_EFF_ATLAS_RUN2(const Particle& y) {
0378 if (y.abspid() != PID::PHOTON) return 0;
0379
0380 if (y.pT() < 10*GeV) return 0;
0381 if (inRange(y.abseta(), 1.37, 1.52) || y.abseta() > 2.37) return 0;
0382
0383 static const vector<double> edges_eta = {0., 0.6, 1.37, 1.52, 1.81, 2.37};
0384 static const vector<double> edges_pt = {10., 15., 20., 25., 30., 35., 40., 45.,
0385 50., 60., 80., 100., 125., 150., 175., 250.};
0386 static const vector<double> effs = {0.55, 0.70, 0.85, 0.89, 0.93, 0.95, 0.96, 0.96,
0387 0.97, 0.97, 0.98, 0.97, 0.97, 0.97, 0.97, 0.97,
0388 0.47, 0.66, 0.79, 0.86, 0.89, 0.94, 0.96, 0.97,
0389 0.97, 0.98, 0.97, 0.98, 0.98, 0.98, 0.98, 0.98,
0390 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
0391 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
0392 0.54, 0.71, 0.84, 0.88, 0.92, 0.93, 0.94, 0.95,
0393 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96,
0394 0.61, 0.74, 0.83, 0.88, 0.91, 0.94, 0.95, 0.96,
0395 0.97, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98};
0396
0397 const int i_eta = binIndex(y.abseta(), edges_eta);
0398 const int i_pt = binIndex(y.pT()/GeV, edges_pt, true);
0399 const int i = i_eta*edges_pt.size() + i_pt;
0400 const double eff = effs[i];
0401 return eff;
0402 }
0403
0404
0405 inline double PHOTON_EFF_ATLAS_RUN2_LOOSE(const Particle& y) { return PHOTON_EFF_ATLAS_RUN2(y); }
0406
0407
0408 inline double PHOTON_EFF_ATLAS_RUN2_MEDIUM(const Particle& y) { return PHOTON_EFF_ATLAS_RUN2(y); }
0409
0410
0411 inline double PHOTON_EFF_ATLAS_RUN2_TIGHT(const Particle& y) { return PHOTON_EFF_ATLAS_RUN2(y); }
0412
0413
0414
0415
0416
0417 inline double PHOTON_EFF_CMS_RUN1(const Particle& y) {
0418 if (y.abspid() != PID::PHOTON) return 0;
0419 if (y.pT() < 10*GeV || y.abseta() > 2.5) return 0;
0420 return (y.abseta() < 1.5) ? 0.95 : 0.85;
0421 }
0422
0423
0424 inline double PHOTON_EFF_CMS_RUN1_LOOSE(const Particle& y) { return PHOTON_EFF_CMS_RUN1(y); }
0425
0426
0427 inline double PHOTON_EFF_CMS_RUN1_MEDIUM(const Particle& y) { return PHOTON_EFF_CMS_RUN1(y); }
0428
0429
0430 inline double PHOTON_EFF_CMS_RUN1_TIGHT(const Particle& y) { return PHOTON_EFF_CMS_RUN1(y); }
0431
0432
0433
0434
0435
0436 inline double PHOTON_EFF_CMS_RUN2(const Particle& y) {
0437 if (y.abspid() != PID::PHOTON) return 0;
0438 return PHOTON_EFF_CMS_RUN1(y);
0439 }
0440
0441
0442 inline double PHOTON_EFF_CMS_RUN2_LOOSE(const Particle& y) { return PHOTON_EFF_CMS_RUN2(y); }
0443
0444
0445 inline double PHOTON_EFF_CMS_RUN2_MEDIUM(const Particle& y) { return PHOTON_EFF_CMS_RUN2(y); }
0446
0447
0448 inline double PHOTON_EFF_CMS_RUN2_TIGHT(const Particle& y) { return PHOTON_EFF_CMS_RUN2(y); }
0449
0450
0451
0452 inline Particle PHOTON_SMEAR_ATLAS_RUN1(const Particle& y) { return y; }
0453 inline Particle PHOTON_SMEAR_ATLAS_RUN2(const Particle& y) { return y; }
0454 inline Particle PHOTON_SMEAR_CMS_RUN1(const Particle& y) { return y; }
0455 inline Particle PHOTON_SMEAR_CMS_RUN2(const Particle& y) { return y; }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 inline double MUON_EFF_ATLAS_RUN1(const Particle& m) {
0466 if (m.abspid() != PID::MUON) return 0;
0467 if (m.abseta() > 2.7) return 0;
0468 if (m.pT() < 10*GeV) return 0;
0469 return (m.abseta() < 1.5) ? 0.95 : 0.85;
0470 }
0471
0472
0473 inline double MUON_EFF_ATLAS_RUN1_LOOSE(const Particle& m) { return MUON_EFF_ATLAS_RUN1(m); }
0474
0475
0476 inline double MUON_EFF_ATLAS_RUN1_MEDIUM(const Particle& m) { return MUON_EFF_ATLAS_RUN1(m); }
0477
0478
0479 inline double MUON_EFF_ATLAS_RUN1_TIGHT(const Particle& m) { return MUON_EFF_ATLAS_RUN1(m); }
0480
0481
0482
0483
0484
0485 inline double MUON_RECOEFF_ATLAS_RUN2(const Particle& m) {
0486 if (m.abspid() != PID::MUON) return 0;
0487 if (m.abseta() > 2.5) return 0;
0488 if (m.abseta() < 0.1) return 0.61;
0489
0490 return (m.abseta() < 1) ? 0.98 : 0.99;
0491 }
0492
0493
0494
0495
0496
0497 inline double MUON_ISOEFF_ATLAS_RUN2_LOOSE(const Particle& m) {
0498 if (m.abspid() != PID::MUON) return 0;
0499 static const vector<double> edges_pt = {0., 3., 4., 5., 6., 7., 8., 9., 10., 15., 20., 30., 40.};
0500 static const vector<double> effs_pt = {0., 0.58, 0.70, 0.75, 0.80, 0.82, 0.85, 0.87, 0.90, 0.95, 0.98, 1.00, 1.00};
0501 const int i_pt = binIndex(m.pT()/GeV, edges_pt, true);
0502 const double eff_pt = effs_pt[i_pt];
0503 return eff_pt;
0504 }
0505
0506
0507
0508
0509
0510 inline double MUON_EFF_ATLAS_RUN2_LOOSE(const Particle& m) {
0511 if (m.abspid() != PID::MUON) return 0;
0512 if (m.abseta() > 2.5) return 0;
0513 static const vector<double> edges_pt = {0., 3.5, 4., 5., 6., 7., 8., 10.};
0514 static const vector<double> effs = {0.00, 0.88, 0.92, 0.97, 0.98, 0.98, 0.98, 0.99};
0515 const int i_pt = binIndex(m.pT()/GeV, edges_pt, true);
0516 const double eff = effs[i_pt];
0517
0518 return eff * MUON_ISOEFF_ATLAS_RUN2_LOOSE(m);
0519 }
0520
0521
0522
0523
0524
0525 inline double MUON_EFF_ATLAS_RUN2_MEDIUM(const Particle& m) {
0526 if (m.abspid() != PID::MUON) return 0;
0527 if (m.abseta() > 2.5) return 0;
0528 static const vector<double> edges_pt = {0., 3.5, 4., 5., 6., 7., 8., 9., 10., 12., 14., 16., 18., 20., 25., 30., 35., 40., 45., 50.};
0529 static const vector<double> effs_pt = {0.00, 0.48, 0.62, 0.82, 0.94, 0.95, 0.96, 0.96, 0.97, 0.97, 0.97, 0.97, 0.97, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98};
0530 const int i_pt = binIndex(m.pT()/GeV, edges_pt, true);
0531 const double eff_pt = effs_pt[i_pt];
0532 static const vector<double> edges_eta = {0., 0.25, 0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00, 2.25, 2.50};
0533 static const vector<double> effs_eta = {0.85, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99, 0.99};
0534 const int i_eta = binIndex(m.abseta(), edges_eta, true);
0535 const double eff_eta = effs_eta[i_eta] / 0.99;
0536 return eff_pt*eff_eta * MUON_ISOEFF_ATLAS_RUN2_LOOSE(m);
0537 }
0538
0539
0540
0541
0542
0543 inline double MUON_EFF_ATLAS_RUN2_TIGHT(const Particle& m) {
0544 if (m.abspid() != PID::MUON) return 0;
0545 if (m.abseta() > 2.5) return 0;
0546 static const vector<double> edges_pt = {0., 3.5, 4., 5., 6., 7., 8., 9., 10., 12., 14., 16., 18., 20.};
0547 static const vector<double> effs_pt = {0.00, 0.00, 0.68, 0.81, 0.85, 0.88, 0.89, 0.90, 0.91, 0.92, 0.92, 0.92, 0.93, 0.93};
0548 const int i_pt = binIndex(m.pT()/GeV, edges_pt, true);
0549 const double eff_pt = effs_pt[i_pt];
0550 static const vector<double> edges_eta = {0., 0.25, 0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00, 2.25, 2.50};
0551 static const vector<double> effs_eta = {0.78, 0.94, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96, 0.96};
0552 const int i_eta = binIndex(m.abseta(), edges_eta, true);
0553 const double eff_eta = effs_eta[i_eta] / 0.96;
0554 return eff_pt*eff_eta * MUON_ISOEFF_ATLAS_RUN2_LOOSE(m);
0555 }
0556
0557
0558
0559
0560
0561
0562 inline Particle MUON_SMEAR_ATLAS_RUN1(const Particle& m) {
0563 static const vector<double> edges_eta = {0, 1.5, 2.5};
0564 static const vector<double> edges_pt = {0, 0.1, 1.0, 10., 200.};
0565 static const vector<double> res = {0., 0.03, 0.02, 0.03, 0.05,
0566 0., 0.04, 0.03, 0.04, 0.05};
0567
0568 const int i_eta = binIndex(m.abseta(), edges_eta);
0569 const int i_pt = binIndex(m.pT()/GeV, edges_pt, true);
0570 const int i = i_eta*edges_pt.size() + i_pt;
0571 const double resolution_fixed = res[i];
0572
0573
0574
0575
0576 const double resolution = resolution_fixed *
0577 (1.0 + max(0.0, (((0.45-0.05)/0.05 - 1.0)/2300) * (m.pT() - 200*GeV)/GeV));
0578
0579
0580
0581
0582
0583
0584 return Particle(m.pid(), P4_SMEAR_PT_GAUSS(m, resolution*m.pT()));
0585 }
0586
0587
0588
0589
0590
0591
0592
0593 inline Particle MUON_SMEAR_ATLAS_RUN2(const Particle& m) {
0594
0595 double mres_pt = 0.015;
0596
0597 if (m.pT() > 50*GeV) mres_pt = 0.015 + 0.01*(m.pT() - 50*GeV)/(50*GeV);
0598
0599 if (m.pT() > 100*GeV) mres_pt = 0.025 + 0.0084*(m.pT() - 100*GeV)/(100*GeV);
0600 const double ptres_pt = SQRT2 * mres_pt;
0601 const double resolution = (m.abseta() < 1.5 ? 1.0 : 1.25) * ptres_pt;
0602 return Particle(m.pid(), P4_SMEAR_PT_GAUSS(m, resolution*m.pT()));
0603 }
0604
0605
0606 inline double MUON_EFF_CMS_RUN1(const Particle& m) {
0607 if (m.abspid() != PID::MUON) return 0;
0608 if (m.abseta() > 2.4) return 0;
0609 if (m.pT() < 10*GeV) return 0;
0610 return 0.95 * (m.abseta() < 1.5 ? 1 : exp(0.5 - 5e-4*m.pT()/GeV));
0611 }
0612
0613
0614
0615 inline double MUON_EFF_CMS_RUN1_LOOSE(const Particle& m) { return MUON_EFF_CMS_RUN1(m); }
0616
0617
0618
0619 inline double MUON_EFF_CMS_RUN1_MEDIUM(const Particle& m) { return MUON_EFF_CMS_RUN1(m); }
0620
0621
0622
0623 inline double MUON_EFF_CMS_RUN1_TIGHT(const Particle& m) { return MUON_EFF_CMS_RUN1(m); }
0624
0625
0626
0627
0628
0629 inline double MUON_EFF_CMS_RUN2(const Particle& m) {
0630 return MUON_EFF_CMS_RUN1(m);
0631 }
0632
0633
0634
0635 inline double MUON_EFF_CMS_RUN2_LOOSE(const Particle& m) { return MUON_EFF_CMS_RUN2(m); }
0636
0637
0638
0639 inline double MUON_EFF_CMS_RUN2_MEDIUM(const Particle& m) { return MUON_EFF_CMS_RUN2(m); }
0640
0641
0642
0643 inline double MUON_EFF_CMS_RUN2_TIGHT(const Particle& m) { return MUON_EFF_CMS_RUN2(m); }
0644
0645
0646
0647
0648 inline Particle MUON_SMEAR_CMS_RUN1(const Particle& m) {
0649
0650
0651
0652
0653 double resolution = 0;
0654 const double abseta = m.abseta();
0655 if (m.pT() > 0.1*GeV && abseta < 2.5) {
0656 if (abseta < 0.5) {
0657 resolution = add_quad(0.01, 2.0e-4 * m.pT()/GeV);
0658 } else if (abseta < 1.5) {
0659 resolution = add_quad(0.02, 3.0e-4 * m.pT()/GeV);
0660 } else {
0661 resolution = add_quad(0.05, 2.6e-4 * m.pT()/GeV);
0662 }
0663 }
0664
0665
0666
0667
0668
0669
0670 return Particle(m.pid(), P4_SMEAR_PT_GAUSS(m, resolution*m.pT()));
0671 }
0672
0673
0674
0675
0676 inline Particle MUON_SMEAR_CMS_RUN2(const Particle& m) {
0677 return MUON_SMEAR_CMS_RUN1(m);
0678 }
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 inline double TAU_EFF_ATLAS_RUN1_MEDIUM(const Particle& t) {
0695 if (t.abseta() > 2.5) return 0;
0696 if (inRange(t.abseta(), 1.37, 1.52)) return 0;
0697 double pThadvis = 0;
0698 Particles chargedhadrons;
0699 for (const Particle& p : t.children()) {
0700 if (p.isHadron()) {
0701 pThadvis += p.pT();
0702 if (p.charge3() != 0 && p.abseta() < 2.5 && p.pT() > 1*GeV) chargedhadrons += p;
0703 }
0704 }
0705 if (chargedhadrons.empty()) return 0;
0706 if (pThadvis < 20*GeV) return 0;
0707 if (pThadvis < 40*GeV) {
0708 if (chargedhadrons.size() == 1) return (t.abspid() == PID::TAU) ? 0.56 : 0;
0709 if (chargedhadrons.size() == 3) return (t.abspid() == PID::TAU) ? 0.38 : 0;
0710 } else {
0711 if (chargedhadrons.size() == 1) return (t.abspid() == PID::TAU) ? 0.56 : 0;
0712 if (chargedhadrons.size() == 3) return (t.abspid() == PID::TAU) ? 0.38 : 0;
0713 }
0714 return 0;
0715 }
0716
0717
0718 inline double TAU_EFF_ATLAS_RUN1(const Particle& t) { return TAU_EFF_ATLAS_RUN1_MEDIUM(t); }
0719
0720
0721 inline double TAU_EFF_ATLAS_RUN1_LOOSE(const Particle& t) { return TAU_EFF_ATLAS_RUN1(t); }
0722
0723
0724 inline double TAU_EFF_ATLAS_RUN1_TIGHT(const Particle& t) { return TAU_EFF_ATLAS_RUN1(t); }
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734 inline double TAUJET_EFF_ATLAS_RUN1(const Jet& j) {
0735 if (j.abseta() > 2.5) return 0;
0736 if (inRange(j.abseta(), 1.37, 1.52)) return 0;
0737 double pThadvis = 0;
0738 Particles chargedhadrons;
0739 for (const Particle& p : j.particles()) {
0740 if (p.isHadron()) {
0741 pThadvis += p.pT();
0742 if (p.charge3() != 0 && p.abseta() < 2.5 && p.pT() > 1*GeV) chargedhadrons += p;
0743 }
0744 }
0745
0746 if (chargedhadrons.empty()) return 0;
0747 if (pThadvis < 20*GeV) return 0;
0748
0749 const Particles ttags = j.tauTags(Cuts::pT > 10*GeV);
0750
0751 if (ttags.empty()) {
0752 if (pThadvis < 40*GeV)
0753 return chargedhadrons.size() == 1 ? 1/20. : chargedhadrons.size() == 3 ? 1/100. : 0;
0754 else
0755 return chargedhadrons.size() == 1 ? 1/25. : chargedhadrons.size() == 3 ? 1/400. : 0;
0756 }
0757
0758 const Particles prongs = ttags[0].stableDescendants(Cuts::charge3 > 0 && Cuts::pT > 1*GeV && Cuts::abseta < 2.5);
0759 return prongs.size() == 1 ? 0.56 : 0.38;
0760 }
0761
0762
0763
0764
0765
0766
0767
0768 inline double TAU_EFF_ATLAS_RUN2_MEDIUM(const Particle& t) {
0769 if (t.abspid() != PID::TAU) return 0;
0770 if (t.abseta() > 2.5) return 0;
0771 if (inRange(t.abseta(), 1.37, 1.52)) return 0;
0772 double pThadvis = 0;
0773 Particles chargedhadrons;
0774 for (const Particle& p : t.children()) {
0775 if (p.isHadron()) {
0776 pThadvis += p.pT();
0777 if (p.charge3() != 0 && p.abseta() < 2.5 && p.pT() > 1*GeV) chargedhadrons += p;
0778 }
0779 }
0780 if (chargedhadrons.empty()) return 0;
0781 if (pThadvis < 20*GeV) return 0;
0782 if (chargedhadrons.size() == 1) return (t.abspid() == PID::TAU) ? 0.55 : 0;
0783 if (chargedhadrons.size() == 3) return (t.abspid() == PID::TAU) ? 0.40 : 0;
0784 return 0;
0785 }
0786
0787
0788 inline double TAU_EFF_ATLAS_RUN2(const Particle& t) { return TAU_EFF_ATLAS_RUN2_MEDIUM(t); }
0789
0790
0791 inline double TAU_EFF_ATLAS_RUN2_LOOSE(const Particle& t) { return TAU_EFF_ATLAS_RUN2(t); }
0792
0793
0794 inline double TAU_EFF_ATLAS_RUN2_TIGHT(const Particle& t) { return TAU_EFF_ATLAS_RUN2(t); }
0795
0796
0797
0798
0799
0800
0801
0802 inline double TAUJET_EFF_ATLAS_RUN2(const Jet& j) {
0803 if (j.abseta() > 2.5) return 0;
0804 if (inRange(j.abseta(), 1.37, 1.52)) return 0;
0805 double pThadvis = 0;
0806 Particles chargedhadrons;
0807 for (const Particle& p : j.particles()) {
0808 if (p.isHadron()) {
0809 pThadvis += p.pT();
0810 if (p.charge3() != 0 && p.abseta() < 2.5 && p.pT() > 1*GeV) chargedhadrons += p;
0811 }
0812 }
0813 if (chargedhadrons.empty()) return 0;
0814 if (pThadvis < 20*GeV) return 0;
0815 const Particles ttags = j.tauTags(Cuts::pT > 10*GeV);
0816
0817
0818
0819
0820
0821
0822 if (ttags.empty()) return chargedhadrons.size() == 1 ? 1/50. : chargedhadrons.size() == 3 ? 1/110. : 0;
0823 const Particles prongs = ttags[0].stableDescendants(Cuts::charge3 > 0 && Cuts::pT > 1*GeV && Cuts::abseta < 2.5);
0824 return prongs.size() == 1 ? 0.55 : 0.40;
0825 }
0826
0827
0828
0829
0830
0831 inline Particle TAU_SMEAR_ATLAS_RUN1(const Particle& t) {
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846 static const vector<double> binedges_pt = {0., 50., 70., 100., 150., 200., 1000., 10000.};
0847 static const vector<double> jer = {0.145, 0.115, 0.095, 0.075, 0.07, 0.05, 0.04, 0.04};
0848 const int ipt = binIndex(t.pT()/GeV, binedges_pt, true);
0849 if (ipt < 0) return t;
0850 const double resolution = jer.at(ipt);
0851
0852
0853
0854 const double fsmear = max(randnorm(1., resolution), 0.);
0855 const double mass = t.mass2() > 0 ? t.mass() : 0;
0856 Particle rtn(PID::TAU, FourMomentum::mkXYZM(t.px()*fsmear, t.py()*fsmear, t.pz()*fsmear, mass));
0857
0858 return rtn;
0859 }
0860
0861
0862
0863
0864
0865 inline Particle TAU_SMEAR_ATLAS_RUN2(const Particle& t) {
0866 return TAU_SMEAR_ATLAS_RUN1(t);
0867 }
0868
0869
0870
0871
0872
0873 inline double TAU_EFF_CMS_RUN1(const Particle& t) {
0874 if (t.abspid() != PID::TAU) return 0;
0875 return (t.abspid() == PID::TAU) ? 0.6 : 0;
0876 }
0877
0878
0879 inline double TAU_EFF_CMS_RUN1_LOOSE(const Particle& t) { return TAU_EFF_CMS_RUN1(t); }
0880
0881
0882 inline double TAU_EFF_CMS_RUN1_MEDIUM(const Particle& t) { return TAU_EFF_CMS_RUN1(t); }
0883
0884
0885 inline double TAU_EFF_CMS_RUN1_TIGHT(const Particle& t) { return TAU_EFF_CMS_RUN1(t); }
0886
0887
0888
0889
0890 inline double TAU_EFF_CMS_RUN2(const Particle& t) {
0891 if (t.abspid() != PID::TAU) return 0;
0892 return (t.abspid() == PID::TAU) ? 0.6 : 0;
0893 }
0894
0895
0896 inline double TAU_EFF_CMS_RUN2_LOOSE(const Particle& t) { return TAU_EFF_CMS_RUN2(t); }
0897
0898
0899 inline double TAU_EFF_CMS_RUN2_MEDIUM(const Particle& t) { return TAU_EFF_CMS_RUN2(t); }
0900
0901
0902 inline double TAU_EFF_CMS_RUN2_TIGHT(const Particle& t) { return TAU_EFF_CMS_RUN2(t); }
0903
0904
0905
0906
0907
0908 inline Particle TAU_SMEAR_CMS_RUN1(const Particle& t) {
0909 return TAU_SMEAR_ATLAS_RUN1(t);
0910 }
0911
0912
0913
0914
0915
0916 inline Particle TAU_SMEAR_CMS_RUN2(const Particle& t) {
0917 return TAU_SMEAR_CMS_RUN1(t);
0918 }
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928 inline double JET_BTAG_ATLAS_RUN1(const Jet& j) {
0929
0930 if (j.abseta() > 2.5) return 0;
0931 const auto ftagsel = [&](const Particle& p){ return p.pT() > 5*GeV && deltaR(p,j) < 0.3; };
0932 if (j.bTagged(ftagsel)) return 0.80*tanh(0.003*j.pT()/GeV)*(30/(1+0.0860*j.pT()/GeV));
0933 if (j.cTagged(ftagsel)) return 0.20*tanh(0.020*j.pT()/GeV)*( 1/(1+0.0034*j.pT()/GeV));
0934 return 0.002 + 7.3e-6*j.pT()/GeV;
0935 }
0936
0937 inline double JET_BTAG_ATLAS_RUN1_XXX(const Jet& j) { return JET_BTAG_ATLAS_RUN1(j); }
0938
0939
0940 inline double JET_BTAG_ATLAS_RUN2_MV2C20(const Jet& j) {
0941 if (j.abseta() > 2.5) return 0;
0942 if (j.bTagged(Cuts::pT > 5*GeV)) return 0.77;
0943 if (j.cTagged(Cuts::pT > 5*GeV)) return 1/4.5;
0944 return 1/140.;
0945 }
0946
0947
0948 inline double JET_BTAG_ATLAS_RUN2_MV2C10(const Jet& j) {
0949 if (j.abseta() > 2.5) return 0;
0950 if (j.bTagged(Cuts::pT > 5*GeV)) return 0.77;
0951 if (j.cTagged(Cuts::pT > 5*GeV)) return 1/6.0;
0952 return 1/134.;
0953 }
0954
0955
0956
0957
0958 inline double JET_BTAG_ATLAS_RUN2_2016_MV2C10_77(const Jet & j){
0959 if (j.bTagged()){
0960
0961
0962
0963
0964
0965
0966 const static vector<double>binedges_pt = {0.00, 30.0, 40.00, 50.00, 60.0, 75.00, 90.0, 105., 150., 200., 500 };
0967 const static vector<double> eff_pt = {0.63, 0.705, 0.74, 0.76, 0.775, 0.785, 0.795, 0.80, 0.79, 0.75, 0.68};
0968
0969 return eff_pt[binIndex(j.pt(), binedges_pt, true)];
0970 }
0971 else if (j.cTagged()){
0972
0973 return 1./5.;
0974 }
0975 else if (j.tauTagged()){
0976 return 1./16.;
0977 }
0978 else return 1./110.;
0979 }
0980
0981
0982
0983 inline double JET_BTAG_ATLAS_RUN2_DL1d_77(const Jet &j){
0984 if (j.bTagged()){
0985 if (j.abseta() > 2.5) return 0.;
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998 const static vector<double>binedges_pt = {0.00, 20., 30., 40., 60., 85., 110., 140., 175., 250., 400., 800., 1200., 2000.};
0999 const static vector<double> eff_pt = {0.68, 0.74, 0.77, 0.79, 0.8, 0.81, 0.81, 0.805, 0.78, 0.75, 0.7, 0.65, 0.5, 0.5};
1000
1001 return eff_pt[binIndex(j.pt(), binedges_pt, true)];
1002 }
1003 else if (j.cTagged()){
1004
1005 return 0.155;
1006 }
1007
1008 else if (j.tauTagged()){
1009 return 1./36.;
1010 }
1011 else return 0.0038;
1012 }
1013
1014
1015
1016
1017
1018
1019 inline double JET_BTAG_ATLAS_RUN2_DL1r_77(const Jet & j){
1020 if (j.pt() <= 20*GeV || j.abseta() > 2.5) return 0.;
1021
1022 const static vector<double>binedges_pt = {20., 30., 40., 60., 85., 110., 140., 175., 210., 250.,
1023 400., 600., 800., 1000., 1200., 1400., 1500., 2000.0, 3000.0 };
1024
1025 if (j.bTagged()){
1026
1027 const static vector<double> eff_pt = {0.667, 0.731, 0.771, 0.791, 0.801, 0.805, 0.806, 0.798, 0.795,
1028 0.825, 0.802, 0.771, 0.741, 0.706, 0.679, 0.674, 0.634, 0.5, 0.5};
1029
1030
1031 return eff_pt[binIndex(j.pt(), binedges_pt, true)];
1032 }
1033 else if (j.cTagged()){
1034 const static vector<double> c_rej_pt = {5.30, 5.23, 5.55, 5.91, 6.13, 6.30, 6.32, 6.50, 6.10,
1035 3.04, 3.05, 3.21, 3.37, 3.616, 3.83, 3.96, 4.01, 2.90, 2.90};
1036
1037 return 1./c_rej_pt[binIndex(j.pt(), binedges_pt, true)];
1038 }
1039 else {
1040 const static vector<double> light_rej_pt = {143, 191, 239, 261, 235, 257, 248, 189, 158,
1041 32.8, 19.1, 14.2, 12.4, 11.2, 11.0, 11.2, 12.4, 8.27, 8.27};
1042
1043 return 1./light_rej_pt[binIndex(j.pt(), binedges_pt, true)];
1044 }
1045 }
1046
1047
1048
1049
1050
1051
1052 inline Jet JET_SMEAR_ATLAS_RUN1(const Jet& j) {
1053
1054
1055
1056 static const vector<double> binedges_pt = {0., 50., 70., 100., 150., 200., 1000., 10000.};
1057 static const vector<double> jer = {0.145, 0.115, 0.095, 0.075, 0.07, 0.05, 0.04, 0.04};
1058 const int ipt = binIndex(j.pT()/GeV, binedges_pt, true);
1059 if (ipt < 0) return j;
1060 const double resolution = jer.at(ipt);
1061
1062
1063
1064 const double fsmear = max(randnorm(1., resolution), 0.);
1065 const double mass = j.mass2() > 0 ? j.mass() : 0;
1066 Jet rtn(FourMomentum::mkXYZM(j.px()*fsmear, j.py()*fsmear, j.pz()*fsmear, mass));
1067
1068 return rtn;
1069 }
1070
1071
1072
1073
1074 inline Jet JET_SMEAR_ATLAS_RUN2(const Jet& j) { return JET_SMEAR_ATLAS_RUN1(j); }
1075
1076
1077
1078
1079 inline Jet JET_SMEAR_CMS_RUN1(const Jet& j) { return JET_SMEAR_ATLAS_RUN1(j); }
1080
1081
1082
1083
1084 inline Jet JET_SMEAR_CMS_RUN2(const Jet& j) { return JET_SMEAR_CMS_RUN1(j); }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 inline METSmearParams MET_SMEARPARAMS_ATLAS_RUN1(const Vector3& met, double set) {
1096
1097 Vector3 smeared_met = met;
1098 if (met.mod() < 25*GeV) smeared_met *= 1.05;
1099 else if (met.mod() < 40*GeV) smeared_met *= (1.05 - (0.04/15)*(met.mod()/GeV - 25));
1100 else smeared_met *= 1.01;
1101
1102 return {smeared_met, 0.45*sqrt(set/GeV)*GeV, 0.0};
1103 }
1104
1105
1106 inline Vector3 MET_SMEAR_ATLAS_RUN1(const Vector3& met, double set) {
1107 return MET_SMEAR_NORM(MET_SMEARPARAMS_ATLAS_RUN1(met, set));
1108 }
1109
1110
1111
1112
1113
1114 inline METSmearParams MET_SMEARPARAMS_ATLAS_RUN2(const Vector3& met, double set) {
1115
1116
1117
1118
1119
1120
1121
1122 const Vector3 smeared_met = met * (1 + 0.45*min(1.0, exp(-(met.mod() - 25*GeV)/(10*GeV))) - 0.02);
1123
1124
1125
1126 const double resolution1 = (set < 180*GeV ? set/180. : 1) * 0.45 * sqrt(max(set/GeV, 180)) * GeV;
1127
1128
1129
1130 const double resolution2 = 15*GeV + 0.5*sqrt(met.mod()/GeV)*GeV;
1131
1132
1133
1134
1135 const double sigma = min(resolution1, resolution2);
1136
1137 return {smeared_met, sigma, 0.0};
1138 }
1139
1140
1141 inline Vector3 MET_SMEAR_ATLAS_RUN2(const Vector3& met, double set) {
1142 return MET_SMEAR_NORM(MET_SMEARPARAMS_ATLAS_RUN2(met, set));
1143 }
1144
1145
1146
1147
1148
1149
1150
1151 inline METSmearParams MET_SMEARPARAMS_ATLAS_RUN2_PFLOW(const Vector3& met, double ) {
1152
1153
1154 const Vector3 smeared_met = met * (1 + 1.15*exp(-met.mod()/(20*GeV)) - 0.01);
1155
1156
1157
1158
1159 const double resolution = 20*GeV;
1160
1161 return {smeared_met, resolution, 0.0};
1162 }
1163
1164
1165 inline Vector3 MET_SMEAR_ATLAS_RUN2_PFLOW(const Vector3& met, double set) {
1166 return MET_SMEAR_NORM(MET_SMEARPARAMS_ATLAS_RUN2_PFLOW(met, set));
1167 }
1168
1169
1170
1171
1172
1173 inline METSmearParams MET_SMEARPARAMS_CMS_RUN1(const Vector3& met, double set) {
1174
1175 const double resolution_x = (1.1 + 0.6*sqrt(set/GeV)) * GeV;
1176 const double resolution_y = (1.4 + 0.6*sqrt(set/GeV)) * GeV;
1177 const double resolution = sqrt(sqr(resolution_x) + sqr(resolution_y));
1178 return {met, resolution,0.0};
1179 }
1180
1181
1182 inline Vector3 MET_SMEAR_CMS_RUN1(const Vector3& met, double set) {
1183 return MET_SMEAR_NORM(MET_SMEARPARAMS_CMS_RUN1(met, set));
1184 }
1185
1186
1187
1188
1189
1190 inline METSmearParams MET_SMEARPARAMS_CMS_RUN2(const Vector3& met, double set) {
1191
1192 const double resolution_para = ( 2.0 + 0.64*sqrt(set/GeV)) * GeV;
1193 const double resolution_perp = (-1.5 + 0.68*sqrt(set/GeV)) * GeV;
1194 const double resolution = sqrt(sqr(resolution_para) + sqr(resolution_perp));
1195 return {met, resolution,0.0};
1196 }
1197
1198
1199 inline Vector3 MET_SMEAR_CMS_RUN2(const Vector3& met, double set) {
1200 return MET_SMEAR_NORM(MET_SMEARPARAMS_CMS_RUN2(met, set));
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210 inline double TRK_EFF_ATLAS_RUN1(const Particle& p) {
1211 if (p.charge3() == 0) return 0;
1212 if (p.abseta() > 2.5) return 0;
1213 if (p.pT() < 0.1*GeV) return 0;
1214
1215 if (p.abspid() == PID::ELECTRON) {
1216 if (p.abseta() < 1.5) {
1217 if (p.pT() < 1*GeV) return 0.73;
1218 if (p.pT() < 100*GeV) return 0.95;
1219 return 0.99;
1220 } else {
1221 if (p.pT() < 1*GeV) return 0.50;
1222 if (p.pT() < 100*GeV) return 0.83;
1223 else return 0.90;
1224 }
1225 } else if (p.abspid() == PID::MUON) {
1226 if (p.abseta() < 1.5) {
1227 return (p.pT() < 1*GeV) ? 0.75 : 0.99;
1228 } else {
1229 return (p.pT() < 1*GeV) ? 0.70 : 0.98;
1230 }
1231 } else {
1232 if (p.abseta() < 1.5) {
1233 return (p.pT() < 1*GeV) ? 0.70 : 0.95;
1234 } else {
1235 return (p.pT() < 1*GeV) ? 0.60 : 0.85;
1236 }
1237 }
1238 }
1239
1240
1241
1242
1243 inline double TRK_EFF_ATLAS_RUN2(const Particle& p) {
1244 return TRK_EFF_ATLAS_RUN1(p);
1245 }
1246
1247
1248
1249
1250
1251 inline Particle TRK_SMEAR_ATLAS_RUN1(const Particle& t) {
1252 return PARTICLE_SMEAR_IDENTITY(t);
1253 }
1254
1255
1256
1257 inline Particle TRK_SMEAR_ATLAS_RUN2(const Particle& t) {
1258 return PARTICLE_SMEAR_IDENTITY(t);
1259 }
1260
1261
1262
1263 inline double TRK_EFF_CMS_RUN1(const Particle& p) {
1264 if (p.charge3() == 0) return 0;
1265 if (p.abseta() > 2.5) return 0;
1266 if (p.pT() < 0.1*GeV) return 0;
1267
1268 if (p.abspid() == PID::ELECTRON) {
1269 if (p.abseta() < 1.5) {
1270 if (p.pT() < 1*GeV) return 0.73;
1271 if (p.pT() < 100*GeV) return 0.95;
1272 return 0.99;
1273 } else {
1274 if (p.pT() < 1*GeV) return 0.50;
1275 if (p.pT() < 100*GeV) return 0.83;
1276 else return 0.90;
1277 }
1278 } else if (p.abspid() == PID::MUON) {
1279 if (p.abseta() < 1.5) {
1280 return (p.pT() < 1*GeV) ? 0.75 : 0.99;
1281 } else {
1282 return (p.pT() < 1*GeV) ? 0.70 : 0.98;
1283 }
1284 } else {
1285 if (p.abseta() < 1.5) {
1286 return (p.pT() < 1*GeV) ? 0.70 : 0.95;
1287 } else {
1288 return (p.pT() < 1*GeV) ? 0.60 : 0.85;
1289 }
1290 }
1291 }
1292
1293
1294
1295
1296 inline double TRK_EFF_CMS_RUN2(const Particle& p) {
1297 return TRK_EFF_CMS_RUN1(p);
1298 }
1299
1300
1301
1302
1303
1304 inline Particle TRK_SMEAR_CMS_RUN1(const Particle& t) {
1305 return PARTICLE_SMEAR_IDENTITY(t);
1306 }
1307
1308
1309
1310 inline Particle TRK_SMEAR_CMS_RUN2(const Particle& t) {
1311 return PARTICLE_SMEAR_IDENTITY(t);
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321 inline double ATLAS_JVT_EFF_LOOSE(const Jet & j){
1322 if (j.abseta() > 2.4) return 1.0;
1323
1324 if (j.pt() <= 20*GeV || j.pt() >= 60*GeV) return 1.0;
1325
1326 const static vector<double> binedges_pt = {20*GeV,25*GeV,30*GeV,35*GeV,40*GeV,45*GeV,50*GeV,55*GeV,60*GeV};
1327 const static vector<double> binvals = {0.9, 0.93, 0.94, 0.95, 0.96, 0.96, 0.97, 0.97};
1328
1329 const size_t bini = binIndex(j.pt(), binedges_pt);
1330 return binvals[bini];
1331 }
1332
1333
1334
1335
1336
1337
1338
1339
1340 inline double ATLAS_JVT_EFF_MEDIUM(const Jet & j){
1341 if (j.abseta() > 2.4) return 1.0;
1342
1343 if (j.pt() <= 20*GeV || j.pt() >= 60*GeV) return 1.0;
1344
1345 const static vector<double> binedges_pt = {20*GeV,25*GeV,30*GeV,35*GeV,40*GeV,45*GeV,50*GeV,55*GeV,60*GeV};
1346 const static vector<double> binvals = {0.86, 0.9, 0.92, 0.93, 0.94, 0.95, 0.95, 0.96};
1347
1348 const size_t bini = binIndex(j.pt(), binedges_pt);
1349 return binvals[bini];
1350 }
1351
1352
1353
1354
1355
1356
1357
1358
1359 inline double ATLAS_JVT_EFF_TIGHT(const Jet & j){
1360 if (j.abseta() > 2.4) return 1.0;
1361
1362 if (j.pt() <= 20*GeV || j.pt() >= 60*GeV) return 1.0;
1363
1364 const static vector<double> binedges_pt = {20*GeV,25*GeV,30*GeV,35*GeV,40*GeV,45*GeV,50*GeV,55*GeV,60*GeV};
1365 const static vector<double> binvals = {0.81, 0.84, 0.87, 0.90, 0.91, 0.92, 0.93, 0.94};
1366
1367 const size_t bini = binIndex(j.pt(), binedges_pt);
1368 return binvals[bini];
1369 }
1370
1371
1372
1373
1374
1375
1376 inline double ELECTRON_EFF_IDENTITY_LOOSE(const Particle& e) { return PARTICLE_EFF_ONE(e); }
1377 inline double ELECTRON_EFF_IDENTITY_MEDIUM(const Particle& e) { return PARTICLE_EFF_ONE(e); }
1378 inline double ELECTRON_EFF_IDENTITY_TIGHT(const Particle& e) { return PARTICLE_EFF_ONE(e); }
1379 inline double MUON_EFF_IDENTITY_LOOSE(const Particle& m) { return PARTICLE_EFF_ONE(m); }
1380 inline double MUON_EFF_IDENTITY_MEDIUM(const Particle& m) { return PARTICLE_EFF_ONE(m); }
1381 inline double MUON_EFF_IDENTITY_TIGHT(const Particle& m) { return PARTICLE_EFF_ONE(m); }
1382 inline double PHOTON_EFF_IDENTITY_LOOSE(const Particle& y) { return PARTICLE_EFF_ONE(y); }
1383 inline double PHOTON_EFF_IDENTITY_MEDIUM(const Particle& y) { return PARTICLE_EFF_ONE(y); }
1384 inline double PHOTON_EFF_IDENTITY_TIGHT(const Particle& y) { return PARTICLE_EFF_ONE(y); }
1385 inline double TAU_EFF_IDENTITY_LOOSE(const Particle& t) { return PARTICLE_EFF_ONE(t); }
1386 inline double TAU_EFF_IDENTITY_MEDIUM(const Particle& t) { return PARTICLE_EFF_ONE(t); }
1387 inline double TAU_EFF_IDENTITY_TIGHT(const Particle& t) { return PARTICLE_EFF_ONE(t); }
1388
1389 inline Particle ELECTRON_SMEAR_IDENTITY(const Particle& e) { return PARTICLE_SMEAR_IDENTITY(e); }
1390 inline Particle MUON_SMEAR_IDENTITY(const Particle& m) { return PARTICLE_SMEAR_IDENTITY(m); }
1391 inline Particle PHOTON_SMEAR_IDENTITY(const Particle& y) { return PARTICLE_SMEAR_IDENTITY(y); }
1392 inline Particle TAU_SMEAR_IDENTITY(const Particle& t) { return PARTICLE_SMEAR_IDENTITY(t); }
1393
1394 inline double TRK_EFF_IDENTITY_TIGHT(const Particle& trk) { return PARTICLE_EFF_ONE(trk); }
1395 inline Particle TRK_SMEAR_IDENTITY(const Particle& trk) { return PARTICLE_SMEAR_IDENTITY(trk); }
1396
1397 inline double JET_BTAG_IDENTITY_IDENTITY(const Jet& j) { return JET_BTAG_IDENTITY(j); }
1398
1399
1400
1401
1402
1403
1404
1405
1406 }
1407
1408 #endif