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, const Jets& js, const Particles&es,
48 const Particles& mus, const Particles& gammas = {}, const Jets& hadtaus = {}) {
49 // Work out soft term contribution by summing out known contributions.
50 ThreeMomentum softVec = MET;
51
52 // TODO: maybe Rivet should just have a Matrix2 class?
53 Matrix<2> cov_sum = Matrix<2>::mkZero();
54 for (const Jet& j : js) {
55 softVec += j.p3();
56 // TODO Working with rivet matrices is not fun
57 const double jptres = _jet_pt_res->resolution(j);
58 const double jphires = _jet_phi_res->resolution(j);
59 const double metangle = directionalDeltaPhi(MET, j.p3());
60
61 update_matrix(cov_sum, jptres, jphires, j.pT2(), metangle);
62 }
63
64 for (const Particle& e : es) {
65 softVec += e.p3();
66 const double etres = _el_et_res->resolution(e);
67 const double phires = _el_phi_res->resolution(e);
68 const double metangle = directionalDeltaPhi(MET, e.p3());
69 update_matrix(cov_sum, etres, phires, e.pt2(), metangle);
70 }
71 for (const Particle& mu : mus) {
72 softVec += mu.p3();
73 const double ptres = _mu_pt_res->resolution(mu);
74 const double phires = _mu_phi_res->resolution(mu);
75 const double metangle = directionalDeltaPhi(MET, mu.p3());
76 update_matrix(cov_sum, ptres, phires, mu.pt2(), metangle);
77 }
78
79 if (_photon_phi_res != nullptr && _photon_pt_res != nullptr) {
80 for (const Particle& gamma : gammas) {
81 softVec += gamma.p3();
82 const double ptres = _photon_pt_res->resolution(gamma);
83 const double phires = _photon_phi_res->resolution(gamma);
84 const double metangle = directionalDeltaPhi(MET, gamma.p3());
85 update_matrix(cov_sum, ptres, phires, gamma.pt2(), metangle);
86 }
87 }
88 // If user provides photons, but not photon resolution functors,
89 // something unintended may be happening.
90 else if (gammas.size() > 0) {
91 // TODO: do we have a way of triggering warnings only once? This will be hit on every event
92 MSG_WARNING("You have passed photons to a ObjectBasedMET calculator without a photon resolution functor."
93 "\n\tThis is probably NOT what you intended to do. Photons will NOT count towards MET significance.");
94 }
95
96
97 if (_hadtau_phi_res != nullptr && _hadtau_pt_res != nullptr){
98 for (const Jet& hadtau : hadtaus) {
99 softVec += hadtau.p3();
100 const double ptres = _hadtau_pt_res->resolution(hadtau);
101 const double phires = _hadtau_phi_res->resolution(hadtau);
102 const double metangle = directionalDeltaPhi(MET, hadtau.p3());
103 update_matrix(cov_sum, ptres, phires, hadtau.pt2(), metangle);
104 }
105 }
106 // If user provides taus, but not tau resolution functors,
107 // something unintended may be happening.
108 else if (gammas.size() > 0) {
109 // TODO: do we have a way of triggering warnings only once? This will be hit on every event
110 MSG_WARNING("You have passed taus to a ObjectBasedMET calculator without a tau resolution functor."
111 "\n\tThis is probably NOT what you intended to do. Taus will NOT count towards MET significance.");
112 }
113
114
115 // Assume 10 GeV resolution from soft term
116 // TODO: Why can't I initialise rivet vectors/matrices with initialiser lists?
117 Matrix<2> softUncert = Matrix<2>::mkIdentity()*100;
118 rotateMatrix2(softUncert, directionalDeltaPhi(MET, softVec));
119 cov_sum += softUncert;
120
121
122 if (cov_sum.get(0,0) == 0) return 0;
123 // Simple analysis includes a check to exclude unphysically? large rho.
124 double rho = cov_sum.get(0, 1)/sqrt(cov_sum.get(0,0)*cov_sum.get(1,1));
125 rho = rho < 0.9 ? rho : 0.;
126 // TODO: The SA code uses a variable called Et, but from my attempts to look inside, Et = pt?
127 const double significance = MET.pT() / sqrt(cov_sum.get(0, 0) * (1-rho*rho));
128
129 // TODO: it would be nice to be able to also return the actual (2D) met resolution to use for smearing?
130 // However, to get a "consistent" smear, we would need both the "true" objects and the "smeared ones"
131 // -- which gets pretty messy pretty fast
132
133 return significance;
134 }
135
136 protected:
137
140
143 void update_matrix(Matrix<2>& mat, const double ptres, const double phires,
144 const double pt2, const double angle) const {
145 Matrix<2> particle_uncert = Matrix<2>::mkZero();
146 particle_uncert.set(0,0, ptres*ptres*pt2);
147 particle_uncert.set(1,1, phires*phires*pt2);
148 rotateMatrix2(particle_uncert, angle);
149 mat += particle_uncert;
150 }
151
153 void rotateMatrix2(Matrix<2>& in, const double phi) const {
154 const double c = cos(phi); const double s = sin(phi);
155 const double cc = c*c; const double ss = s*s; const double cs = c*s;
156
157 const double _00 = in.get(0,0)*cc + in.get(1,1)*ss - cs*(in.get(1,0)+in.get(0,1));
158 const double _01 = in.get(0,1)*cc - in.get(1,0)*ss + cs*(in.get(0,0)-in.get(1,1));
159 const double _10 = in.get(1,0)*cc - in.get(0,1)*ss + cs*(in.get(0,0)-in.get(1,1));
160 const double _11 = in.get(0,0)*ss + in.get(1,1)*cc - cs*(in.get(1,0)+in.get(0,1));
161
162 in.set(0,0,_00);
163 in.set(1,0,_10);
164 in.set(0,1,_01);
165 in.set(1,1,_11);
166 }
167
170 double directionalDeltaPhi(const ThreeMomentum& first, const ThreeMomentum& second) const {
171 double dPhi = first.phi() - second.phi();
172 if (dPhi > PI/2.) return dPhi - PI;
173 if (dPhi < - PI/2.) return dPhi + PI;
174 return dPhi;
175 }
176
177
178
181 ResolutionFunctorPtr<Jet> _jet_pt_res;
182 ResolutionFunctorPtr<Jet> _jet_phi_res;
183
184 ResolutionFunctorPtr<Particle> _el_et_res;
185 ResolutionFunctorPtr<Particle> _el_phi_res;
186
187 ResolutionFunctorPtr<Particle> _mu_pt_res;
188 ResolutionFunctorPtr<Particle> _mu_phi_res;
189
190 ResolutionFunctorPtr<Particle> _photon_pt_res;
191 ResolutionFunctorPtr<Particle> _photon_phi_res;
192
193 ResolutionFunctorPtr<Jet> _hadtau_pt_res;
194 ResolutionFunctorPtr<Jet> _hadtau_phi_res;
195
197
200 return Rivet::Log::getLog("Rivet.ObjectBaseMET");
201 }
202
203 };
204
206 template <typename jet_pt_res, typename jet_phi_res, typename el_pt_res,
207 typename el_phi_res, typename mu_pt_res, typename mu_phi_res,
208 typename photon_pt_res = void, typename photon_phi_res = void,
209 typename tau_pt_res = void, typename tau_phi_res = void>
211
212 // Deal with possible default arguments
213 ResolutionFunctorPtr<Particle> photon_pt_ptr = nullptr;
214 ResolutionFunctorPtr<Particle> photon_phi_ptr = nullptr;
215 ResolutionFunctorPtr<Jet> tau_pt_ptr = nullptr;
216 ResolutionFunctorPtr<Jet> tau_phi_ptr = nullptr;
217
218 if constexpr (!std::is_void_v<photon_pt_res>) {
219 photon_pt_ptr = std::make_unique<photon_pt_res>();
220 if constexpr (!std::is_void_v<photon_phi_res>) {
221 photon_phi_ptr = std::make_unique<photon_phi_res>();
222 }
223 }
224 if constexpr (!std::is_void_v<tau_pt_res>) {
225 tau_pt_ptr = std::make_unique<tau_pt_res>();
226 if constexpr (!std::is_void_v<tau_phi_res>) {
227 tau_phi_ptr = std::make_unique<tau_phi_res>();
228 }
229 }
230
231 return ObjectBasedMET(std::make_unique<jet_pt_res>(),
232 std::make_unique<jet_phi_res>(),
233 std::make_unique<el_pt_res>(),
234 std::make_unique<el_phi_res>(),
235 std::make_unique<mu_pt_res>(),
236 std::make_unique<mu_phi_res>(),
237 std::move(photon_pt_ptr),
238 std::move(photon_phi_ptr),
239 std::move(tau_pt_ptr),
240 std::move(tau_phi_ptr));
241 }
242
247
250
253 // Photons and Taus deliberately excluded because unvalidated.
254 // If you need either of them, you can add them by manually
255 // constructing the ObjectBasedMET object.
256 // Check them carefully (and let us know if they work!)
257 }
258
259}
260
261#endif
Definition ExptResolutionFunctions.hh:83
Returns 0.004 as in SimpleAnalysisFramework/src/ObjectResolutions.cxx.
Definition ExptResolutionFunctions.hh:253
Definition ExptResolutionFunctions.hh:13
Definition ExptResolutionFunctions.hh:45
Returns 0.001 as in SimpleAnalysisFramework/src/ObjectResolutions.cxx.
Definition ExptResolutionFunctions.hh:245
Definition ExptResolutionFunctions.hh:123
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:199
Specialised vector of Particle objects.
Definition Particle.hh:21
Specialized version of the ThreeVector with momentum functionality.
Definition Vector3.hh:349
double pT() const
Calculate the transverse momentum .
Definition Vector3.hh:442
double phi(const PhiMapping mapping=ZERO_2PI) const
Synonym for azimuthalAngle.
Definition Vector3.hh:182
#define MSG_WARNING(x)
Warning messages for non-fatal bad things, using MSG_LVL.
Definition Logging.hh:187
void update_matrix(Matrix< 2 > &mat, const double ptres, const double phires, const double pt2, const double angle) const
Definition ObjectBasedMET.hh:143
double directionalDeltaPhi(const ThreeMomentum &first, const ThreeMomentum &second) const
Definition ObjectBasedMET.hh:170
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:153
Definition MC_CENT_PPB_Projections.hh:10
ObjectBasedMET makeObjectBasedMET()
Factory function to avoid the need for make_unique<> unpleasantness.
Definition ObjectBasedMET.hh:210
ObjectBasedMET ATLAS_RUN2_DEFAULT_METSIG()
ObjectBasedMET object using ATLAS Run 2 defaults.
Definition ObjectBasedMET.hh:244
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:177
STL namespace.