Rivet API documentation

Rivet 4.1.3
ObjectBasedMET.hh
1// -*- C++ -*-
2#ifndef RIVET_TOOLS_OBJECTBASEDMET_HH
3#define RIVET_TOOLS_OBJECTBASEDMET_HH
4
5#include "Rivet/Tools/ExptResolutionFunctions.hh"
6
7namespace Rivet {
8
15 public:
16
19
21 ObjectBasedMET(ResolutionFunctorPtr<Jet> jet_pt_res,
22 ResolutionFunctorPtr<Jet> jet_phi_res,
23
24 ResolutionFunctorPtr<Particle> el_et_res,
25 ResolutionFunctorPtr<Particle> el_phi_res,
26
27 ResolutionFunctorPtr<Particle> mu_pt_res,
28 ResolutionFunctorPtr<Particle> mu_phi_res,
29
30 ResolutionFunctorPtr<Particle> photon_pt_res = nullptr,
31 ResolutionFunctorPtr<Particle> photon_phi_res = nullptr,
32
33 ResolutionFunctorPtr<Jet> hadtau_pt_res = nullptr,
34 ResolutionFunctorPtr<Jet> hadtau_phi_res = nullptr)
35 : _jet_pt_res(std::move(jet_pt_res)),
36 _jet_phi_res(std::move(jet_phi_res)),
37 _el_et_res(std::move(el_et_res)),
38 _el_phi_res(std::move(el_phi_res)),
39 _mu_pt_res(std::move(mu_pt_res)),
40 _mu_phi_res(std::move(mu_phi_res)),
41 _photon_pt_res(std::move(photon_pt_res)),
42 _photon_phi_res(std::move(photon_phi_res)),
43 _hadtau_pt_res(std::move(hadtau_pt_res)),
44 _hadtau_phi_res(std::move(hadtau_phi_res)) { }
45
47 double sig(const ThreeMomentum& MET,
48 const Jets& js,
49 const Particles& es,
50 const Particles& mus,
51 const Particles& gammas = {},
52 const Jets& hadtaus = {}) {
53 // Work out soft term contribution by summing out known contributions.
54 ThreeMomentum softVec = MET;
55
56 // TODO: maybe Rivet should just have a Matrix2 class?
57 Matrix<2> cov_sum = Matrix<2>::mkZero();
58 for (const Jet& j : js) {
59 softVec += j.p3();
60 // TODO Working with rivet matrices is not fun
61 const double jptres = _jet_pt_res->resolution(j);
62 const double jphires = _jet_phi_res->resolution(j);
63 const double metangle = directionalDeltaPhi(MET, j.p3());
64
65 update_matrix(cov_sum, jptres, jphires, j.pT2(), metangle);
66 }
67
68 for (const Particle& e : es) {
69 softVec += e.p3();
70 const double etres = _el_et_res->resolution(e);
71 const double phires = _el_phi_res->resolution(e);
72 const double metangle = directionalDeltaPhi(MET, e.p3());
73 update_matrix(cov_sum, etres, phires, e.pt2(), metangle);
74 }
75 for (const Particle& mu : mus) {
76 softVec += mu.p3();
77 const double ptres = _mu_pt_res->resolution(mu);
78 const double phires = _mu_phi_res->resolution(mu);
79 const double metangle = directionalDeltaPhi(MET, mu.p3());
80 update_matrix(cov_sum, ptres, phires, mu.pt2(), metangle);
81 }
82
83 if (_photon_phi_res != nullptr && _photon_pt_res != nullptr) {
84 for (const Particle& gamma : gammas) {
85 softVec += gamma.p3();
86 const double ptres = _photon_pt_res->resolution(gamma);
87 const double phires = _photon_phi_res->resolution(gamma);
88 const double metangle = directionalDeltaPhi(MET, gamma.p3());
89 update_matrix(cov_sum, ptres, phires, gamma.pt2(), metangle);
90 }
91 }
92 // If user provides photons, but not photon resolution functors,
93 // something unintended may be happening.
94 else if (gammas.size() > 0) {
95 // TODO: do we have a way of triggering warnings only once? This will be hit on every event
97 "You have passed photons to a ObjectBasedMET calculator without a photon resolution functor."
98 "\n\tThis is probably NOT what you intended to do. Photons will NOT count towards MET "
99 "significance.");
100 }
101
102
103 if (_hadtau_phi_res != nullptr && _hadtau_pt_res != nullptr) {
104 for (const Jet& hadtau : hadtaus) {
105 softVec += hadtau.p3();
106 const double ptres = _hadtau_pt_res->resolution(hadtau);
107 const double phires = _hadtau_phi_res->resolution(hadtau);
108 const double metangle = directionalDeltaPhi(MET, hadtau.p3());
109 update_matrix(cov_sum, ptres, phires, hadtau.pt2(), metangle);
110 }
111 }
112 // If user provides taus, but not tau resolution functors,
113 // something unintended may be happening.
114 else if (gammas.size() > 0) {
115 // TODO: do we have a way of triggering warnings only once? This will be hit on every event
116 MSG_WARNING("You have passed taus to a ObjectBasedMET calculator without a tau resolution functor."
117 "\n\tThis is probably NOT what you intended to do. Taus will NOT count towards MET "
118 "significance.");
119 }
120
121
122 // Assume 10 GeV resolution from soft term
123 // TODO: Why can't I initialise rivet vectors/matrices with initialiser lists?
124 Matrix<2> softUncert = Matrix<2>::mkIdentity() * 100;
125 rotateMatrix2(softUncert, directionalDeltaPhi(MET, softVec));
126 cov_sum += softUncert;
127
128
129 if (cov_sum.get(0, 0) == 0) return 0;
130 // Simple analysis includes a check to exclude unphysically? large rho.
131 double rho = cov_sum.get(0, 1) / sqrt(cov_sum.get(0, 0) * cov_sum.get(1, 1));
132 rho = rho < 0.9 ? rho : 0.;
133 // TODO: The SA code uses a variable called Et, but from my attempts to look inside, Et = pt?
134 const double significance = MET.pT() / sqrt(cov_sum.get(0, 0) * (1 - rho * rho));
135
136 // TODO: it would be nice to be able to also return the actual (2D) met resolution to use for smearing?
137 // However, to get a "consistent" smear, we would need both the "true" objects and the "smeared ones"
138 // -- which gets pretty messy pretty fast
139
140 return significance;
141 }
142
143 protected:
144
147
151 const double ptres,
152 const double phires,
153 const double pt2,
154 const double angle) const {
155 Matrix<2> particle_uncert = Matrix<2>::mkZero();
156 particle_uncert.set(0, 0, ptres * ptres * pt2);
157 particle_uncert.set(1, 1, phires * phires * pt2);
158 rotateMatrix2(particle_uncert, angle);
159 mat += particle_uncert;
160 }
161
163 void rotateMatrix2(Matrix<2>& in, const double phi) const {
164 const double c = cos(phi);
165 const double s = sin(phi);
166 const double cc = c * c;
167 const double ss = s * s;
168 const double cs = c * s;
169
170 const double _00 = in.get(0, 0) * cc + in.get(1, 1) * ss - cs * (in.get(1, 0) + in.get(0, 1));
171 const double _01 = in.get(0, 1) * cc - in.get(1, 0) * ss + cs * (in.get(0, 0) - in.get(1, 1));
172 const double _10 = in.get(1, 0) * cc - in.get(0, 1) * ss + cs * (in.get(0, 0) - in.get(1, 1));
173 const double _11 = in.get(0, 0) * ss + in.get(1, 1) * cc - cs * (in.get(1, 0) + in.get(0, 1));
174
175 in.set(0, 0, _00);
176 in.set(1, 0, _10);
177 in.set(0, 1, _01);
178 in.set(1, 1, _11);
179 }
180
183 double directionalDeltaPhi(const ThreeMomentum& first, const ThreeMomentum& second) const {
184 double dPhi = first.phi() - second.phi();
185 if (dPhi > PI / 2.) return dPhi - PI;
186 if (dPhi < -PI / 2.) return dPhi + PI;
187 return dPhi;
188 }
189
190
191
194 ResolutionFunctorPtr<Jet> _jet_pt_res;
195 ResolutionFunctorPtr<Jet> _jet_phi_res;
196
197 ResolutionFunctorPtr<Particle> _el_et_res;
198 ResolutionFunctorPtr<Particle> _el_phi_res;
199
200 ResolutionFunctorPtr<Particle> _mu_pt_res;
201 ResolutionFunctorPtr<Particle> _mu_phi_res;
202
203 ResolutionFunctorPtr<Particle> _photon_pt_res;
204 ResolutionFunctorPtr<Particle> _photon_phi_res;
205
206 ResolutionFunctorPtr<Jet> _hadtau_pt_res;
207 ResolutionFunctorPtr<Jet> _hadtau_phi_res;
208
210
213 return Rivet::Log::getLog("Rivet.ObjectBaseMET");
214 }
215 };
216
218 template <typename jet_pt_res,
219 typename jet_phi_res,
220 typename el_pt_res,
221 typename el_phi_res,
222 typename mu_pt_res,
223 typename mu_phi_res,
224 typename photon_pt_res = void,
225 typename photon_phi_res = void,
226 typename tau_pt_res = void,
227 typename tau_phi_res = void>
229
230 // Deal with possible default arguments
231 ResolutionFunctorPtr<Particle> photon_pt_ptr = nullptr;
232 ResolutionFunctorPtr<Particle> photon_phi_ptr = nullptr;
233 ResolutionFunctorPtr<Jet> tau_pt_ptr = nullptr;
234 ResolutionFunctorPtr<Jet> tau_phi_ptr = nullptr;
235
236 if constexpr (!std::is_void_v<photon_pt_res>) {
237 photon_pt_ptr = std::make_unique<photon_pt_res>();
238 if constexpr (!std::is_void_v<photon_phi_res>) {
239 photon_phi_ptr = std::make_unique<photon_phi_res>();
240 }
241 }
242 if constexpr (!std::is_void_v<tau_pt_res>) {
243 tau_pt_ptr = std::make_unique<tau_pt_res>();
244 if constexpr (!std::is_void_v<tau_phi_res>) {
245 tau_phi_ptr = std::make_unique<tau_phi_res>();
246 }
247 }
248
249 return ObjectBasedMET(std::make_unique<jet_pt_res>(), std::make_unique<jet_phi_res>(),
250 std::make_unique<el_pt_res>(), std::make_unique<el_phi_res>(),
251 std::make_unique<mu_pt_res>(), std::make_unique<mu_phi_res>(),
252 std::move(photon_pt_ptr), std::move(photon_phi_ptr), std::move(tau_pt_ptr),
253 std::move(tau_phi_ptr));
254 }
255
259
261
263 // Photons and Taus deliberately excluded because unvalidated.
264 // If you need either of them, you can add them by manually
265 // constructing the ObjectBasedMET object.
266 // Check them carefully (and let us know if they work!)
267 }
268
269}
270
271#endif
Definition ExptResolutionFunctions.hh:85
Returns 0.004 as in SimpleAnalysisFramework/src/ObjectResolutions.cxx.
Definition ExptResolutionFunctions.hh:262
Definition ExptResolutionFunctions.hh:13
Definition ExptResolutionFunctions.hh:46
Returns 0.001 as in SimpleAnalysisFramework/src/ObjectResolutions.cxx.
Definition ExptResolutionFunctions.hh:249
Definition ExptResolutionFunctions.hh:127
Specialised vector of Jet objects.
Definition Jet.hh:21
Logging system for controlled & formatted writing to stdout.
Definition Logging.hh:10
static Log & getLog(const std::string &name)
General -dimensional mathematical matrix object.
Definition MatrixN.hh:30
Definition ObjectBasedMET.hh:14
ObjectBasedMET()
Nullary constructor.
Definition ObjectBasedMET.hh:18
ObjectBasedMET(ResolutionFunctorPtr< Jet > jet_pt_res, ResolutionFunctorPtr< Jet > jet_phi_res, ResolutionFunctorPtr< Particle > el_et_res, ResolutionFunctorPtr< Particle > el_phi_res, ResolutionFunctorPtr< Particle > mu_pt_res, ResolutionFunctorPtr< Particle > mu_phi_res, ResolutionFunctorPtr< Particle > photon_pt_res=nullptr, ResolutionFunctorPtr< Particle > photon_phi_res=nullptr, ResolutionFunctorPtr< Jet > hadtau_pt_res=nullptr, ResolutionFunctorPtr< Jet > hadtau_phi_res=nullptr)
Primary constructor.
Definition ObjectBasedMET.hh:21
double sig(const ThreeMomentum &MET, const Jets &js, const Particles &es, const Particles &mus, const Particles &gammas={}, const Jets &hadtaus={})
Calculate MET significance given the MET and other objects from event.
Definition ObjectBasedMET.hh:47
Rivet::Log & getLog() const
Get Logger object.
Definition ObjectBasedMET.hh:212
Specialised vector of Particle objects.
Definition Particle.hh:21
Specialized version of the ThreeVector with momentum functionality.
Definition Vector3.hh:377
double pT() const
Calculate the transverse momentum $p_T$.
Definition Vector3.hh:487
double phi(const PhiMapping mapping=ZERO_2PI) const
Synonym for azimuthalAngle.
Definition Vector3.hh:212
#define MSG_WARNING(x)
Warning messages for non-fatal bad things, using MSG_LVL.
Definition Logging.hh:200
void update_matrix(Matrix< 2 > &mat, const double ptres, const double phires, const double pt2, const double angle) const
Definition ObjectBasedMET.hh:150
double directionalDeltaPhi(const ThreeMomentum &first, const ThreeMomentum &second) const
Definition ObjectBasedMET.hh:183
void rotateMatrix2(Matrix< 2 > &in, const double phi) const
Rotate the (pt, phi) 2D matrix in in (x,y) space by phi.
Definition ObjectBasedMET.hh:163
Definition LHCbCommon.hh:9
ObjectBasedMET makeObjectBasedMET()
Factory function to avoid the need for make_unique<> unpleasantness.
Definition ObjectBasedMET.hh:228
ObjectBasedMET ATLAS_RUN2_DEFAULT_METSIG()
ObjectBasedMET object using ATLAS Run 2 defaults.
Definition ObjectBasedMET.hh:257
constexpr double PI
Definition MathConstants.hh:13
double angle(const Vector2 &a, const Vector2 &b)
Angle (in radians) between two 2-vectors.
Definition Vector2.hh:194
STL namespace.