HackAnalysis  2
Vectors3.h
1 // -*- C++ -*-
2 //
3 // This file is part of HEPUtils -- https://bitbucket.org/andybuckley/heputils
4 // Copyright (C) 2013-2018 Andy Buckley <andy.buckley@cern.ch>
5 //
6 // Embedding of HEPUtils code in other projects is permitted provided this
7 // notice is retained and the HEPUtils namespace and include path are changed.
8 //
9 
10 // Duly: HEPUtils namespace changed to HEP
11 // Some edits by Mark Goodsell: changed everything round so that we use
12 // (px, py, pz, E) instead of the mass, because I want to use it for spacetime vectors!
13 // Necessary for production/decay vertices etc
14 //
15 
16 #pragma once
17 
18 #include "MathUtils.h"
19 #include "Utils.h"
20 #include <sstream>
21 #include <iostream>
22 #include <stdexcept>
23 #include <cmath>
24 #include "ExHEPUtils/Vectors.h"
25 
28 
30 
31 namespace HEP {
32 
33 
34 class P3 {
35  private:
36 
38 
39  double _x, _y, _z;
41 
42 
43  public:
44 
46 
47 
49  P3()
50  : _x(0), _y(0), _z(0) { }
51 
53  P3(double px, double py, double pz) {
54  setP(px, py, pz);
55  }
56 
58  P3(const P3& v)
59  : _x(v._x), _y(v._y), _z(v._z) { }
60 
62  P3& operator = (const P3& v) {
63  _x = v._x;
64  _y = v._y;
65  _z = v._z;
66  return *this;
67  }
68 
70  void clear() {
71  _x = 0;
72  _y = 0;
73  _z = 0;
74  }
75 
77 
78 
80 
81 
83  static P3 mkXYZ(double px, double py, double pz) {
84  return P3().setP(px, py, pz);
85  }
86 
87  static P3 mkXY(double px, double py) {
88  return P3().setXY(px, py);
89  }
90 
92  static P3 mkEtaPhiP(double eta, double phi, double P) {
93  return P3().setEtaPhiP(eta, phi, P);
94  }
95 
97  static P3 mkEtaPhiPt(double eta, double phi, double pt) {
98  return P3().setEtaPhiPt(eta, phi, pt);
99  }
100 
102  static P3 mkThetaPhiP(double theta, double phi, double P) {
103  return P3().setThetaPhiP(theta, phi, P);
104  }
105 
107  static P3 mkThetaPhiPt(double theta, double phi, double pt) {
108  return P3().setThetaPhiPt(theta, phi, pt);
109  }
110 
111 
113 
114 
116 
117 
119  P3& setPx(double px) {
120  _x = px;
121  return *this;
122  }
123 
125  P3& setPy(double py) {
126  _y = py;
127  return *this;
128  }
129 
131  P3& setPz(double pz) {
132  _z = pz;
133  return *this;
134  }
135 
136 
138  P3& setP(double px, double py, double pz) {
139 
140  setPx(px); setPy(py); setPz(pz);
141  return *this;
142  }
144  P3& SetXYZ(double px, double py, double pz) {
145  return setP(px, py, pz);
146  }
147 
149  P3& setXY(double px, double py) {
150  setPx(px); setPy(py);
151  return *this;
152  }
153 
154 
159  P3& setEtaPhiP(double eta, double phi, double P) {
160 
161  if (P < 0)
162  throw std::invalid_argument("Negative momentum given as argument");
163  const double theta = 2 * atan(exp(-eta));
164  if (theta < 0 || theta > M_PI)
165  throw std::domain_error("Polar angle outside 0..pi in calculation");
166  setThetaPhiP(theta, phi,P);
167  return *this;
168  }
169 
174  P3& setEtaPhiPt(double eta, double phi, double pt) {
175 
176  if (pt < 0)
177  throw std::invalid_argument("Negative transverse momentum given as argument");
178  const double theta = 2 * atan(exp(-eta));
179  if (theta < 0 || theta > M_PI)
180  throw std::domain_error("Polar angle outside 0..pi in calculation");
181  const double p = pt / sin(theta);
182 
183  setThetaPhiP(theta, phi, p);
184  return *this;
185  }
186 
192  P3& setThetaPhiP(double theta, double phi, double p) {
193  if (theta < 0 || theta > M_PI)
194  throw std::invalid_argument("Polar angle outside 0..pi given as argument");
195 
196  if (p < 0)
197  throw std::invalid_argument("Negative momentum given as argument");
198 
199  const double pz = p * cos(theta);
200  const double pt = p * sin(theta);
201  if (pt < 0)
202  throw std::invalid_argument("Negative transverse momentum in calculation");
203  const double px = pt * cos(phi);
204  const double py = pt * sin(phi);
205  //setPM(px, py, pz, mass);
206  setP(px, py, pz);
207  return *this;
208  }
209 
215  P3& setThetaPhiPt(double theta, double phi, double pt) {
216  if (theta < 0 || theta > M_PI)
217  throw std::invalid_argument("Polar angle outside 0..pi given as argument");
218  if (pt < 0)
219  throw std::invalid_argument("Negative transverse momentum given as argument");
220  const double p = pt / sin(theta);
221  const double px = pt * cos(phi);
222  const double py = pt * sin(phi);
223  const double pz = p * cos(theta);
224 
225  setP(px, py, pz);
226  return *this;
227  }
228 
229 
230 
231 
233 
234 
236  double px2() const { return sqr(_x); }
238  double px() const { return _x; }
240  double py2() const { return sqr(_y); }
242  double py() const { return _y; }
244  double pz2() const { return sqr(_z); }
246  double pz() const { return _z; }
247 
248  double X() const { return _x; }
250  double Y() const { return _y; }
252  double Z() const { return _z; }
253 
254 
255 
256 
257  double p2() const { return sqr(px()) + sqr(py()) + sqr(pz()); }
259  double p() const { return sqrt(p2()); }
261  double rho2() const { return sqr(px()) + sqr(py()); }
262  double Perp2() const { return sqr(px()) + sqr(py()); }
264  double rho() const { return sqrt(rho2()); }
265  double Perp() const { return sqrt(Perp2()); }
267  double pT2() const { return Perp2(); }
269  double pT() const { return Perp(); }
270 
271 
272 
274  double phi() const { if (Perp2() == 0) return 0; else return atan2(py(),px()); }
276  double theta() const { if (p2() == 0) return 0; else if (pz() == 0) return M_PI; else return atan2(rho(),pz()); }
278  double eta() const { return -log(tan( 0.5 * theta() )); } //< Optimise with a trig reln on tan(x/2) to avoid tan(atan(..)/2)?
280  double abseta() const { return fabs(eta()); }
281 
282 
283 
285 
286 
288 
289 
291  double dot3(const P3& v) const { return px()*v.px() + py()*v.py() + pz()*v.pz(); }
292 
293  double Dot(const P3& v) const { return px()*v.px() + py()*v.py() + pz()*v.pz(); }
294 
296  double angleTo(const P3& v) const { return acos( dot3(v) /p()/v.p() ); }
297  double Angle(const P3& v) const { return acos( dot3(v) /p()/v.p() ); } // for compatibility with TVector3
299  double deltaPhi(const P3& v) const { return deltaphi(phi(), v.phi()); }
301  double deltaEta(const P3& v) const { return fabs(eta() - v.eta()); }
303  double deltaR2_eta(const P3& v) const { return sqr(deltaEta(v)) + sqr(deltaPhi(v)); }
305  double deltaR_eta(const P3& v) const { return sqrt(deltaR2_eta(v)); }
307 
308  //hahahahaha
309  P3 Cross(const P3& v) const { return P3(py()*v.pz()- pz()*v.py(),pz()*v.px()-px()-v.pz(),px()*v.py()-py()*v.px());}
310 
311  // Reinvent the wheel for similarity with root TVector3
312  // Need: Unit(), Mag(),
313  // https://root.cern.ch/doc/master/classTVector3.html
314 
315  double Mag() const { return p();}
316  double Mag2() const { return p2();}
317  double Theta() const { return theta();}
318  double Phi() const { return phi();}
319 
320  double CosTheta() const { double pp = p(); if (pp == 0.0) return 0.0; else return pz()/pp; }
321 
322  // Unit vector parallel
323  P3 Unit() const {
324  double pp=p();
325  return P3(px()/pp,py()/pp,pz()/pp);
326  }
327 
328  // Unit vector orthogonal ??
329 
330  //P3 Orthogonal() const {
331  //}
332 
333  // rotate around a given axis, modifies the object
334  // https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
335  // v = v|| + v_perp
336  // v|| = (v.axis.Unit()) axis.Unit()
337  // v_perp = v - v||
338 
339 
340  // v * costheta + (k x v) sintheta + k (k.v) (1-costheta)
341 
342  P3& Rotate(const double &angle, const P3& axis) {
343  P3 unitaxis=axis.Unit();
344  double costheta=cos(angle);
345  double sintheta=sin(angle);
346  P3 kcrossv = Cross(unitaxis);
347  double axismultiplier=Dot(unitaxis)*(1.0 - costheta);
348  setPx(px()*costheta+kcrossv.px()*sintheta+unitaxis.px()*axismultiplier);
349  setPy(py()*costheta+kcrossv.py()*sintheta+unitaxis.py()*axismultiplier);
350  setPz(pz()*costheta+kcrossv.pz()*sintheta+unitaxis.pz()*axismultiplier);
351 
352  return (*this);
353  }
354 
356 
358 
359  //P4 operator - () const { P4 rtn; return rtn.setPM(-_x, -_y, -_z, _m); } //< Not self-modifying...
360  //P4& operator += (const P4& v) { double e = E() + v.E(); _x += v.px(); _y += v.py(); _z += v.pz(); _m = sqrt( sqr(e) - p2() ); return *this; }
361  //P4& operator -= (const P4& v) { double e = E() - v.E(); _x -= v.px(); _y -= v.py(); _z -= v.pz(); _m = sqrt( sqr(e) - p2() ); return *this; }
362  //P4& operator *= (double a) { _x *= a; _y *= a; _z *= a; _m *= a; return *this; }
363  //P4& operator /= (double a) { _x /= a; _y /= a; _z /= a; _m /= a; return *this; }
364 
365  P3 operator - () const { P3 rtn; return rtn.setP(-_x, -_y, -_z); } //< Not self-modifying...
366  P3& operator += (const P3& v) { _x += v.px(); _y += v.py(); _z += v.pz() ; return *this; }
367  P3& operator -= (const P3& v) { _x -= v.px(); _y -= v.py(); _z -= v.pz() ; return *this; }
368  P3& operator *= (double a) { _x *= a; _y *= a; _z *= a; return *this; }
369  P3& operator /= (double a) { _x /= a; _y /= a; _z /= a; return *this; }
370 
372 
373  };
374 
375 
377 
378 
380  inline std::string to_str(const P3& p3) {
381  std::stringstream ss;
382  ss << "(" << p3.px() << ", " << p3.py() << ", " << p3.pz() << ")";
383  return ss.str();
384  }
385 
387  inline std::ostream& operator <<(std::ostream& ostr, const P3& p3) {
388  ostr << to_str(p3);
389  return ostr;
390  }
391 
393 
394 
396 
397 
399  inline double Dot(const P3& a, const P3& b) {
400  return a.Dot(b);
401  }
402 
403 
405  inline double angle(const P3& a, const P3& b) {
406  return a.angleTo(b);
407  }
408 
409 
411  inline double deltaPhi(const P3& a, const P3& b) {
412  return a.deltaPhi(b);
413  }
414 
415 
417  inline double deltaEta(const P3& a, const P3& b) {
418  return a.deltaEta(b);
419  }
420 
421 
422 
424  inline double deltaR2_eta(const P3& a, const P3& b) {
425  return a.deltaR2_eta(b);
426  }
428  inline double deltaR_eta(const P3& a, const P3& b) {
429  return a.deltaR_eta(b);
430  }
431 
432 
433 
435 
436 
438 
439  inline P3 operator + (const P3& a, const P3& b) { P3 rtn = a; return rtn += b; }
440  inline P3 operator - (const P3& a, const P3& b) { P3 rtn = a; return rtn -= b; }
441  inline P3 operator * (const P3& a, double f) { P3 rtn = a; return rtn *= f; }
442  inline P3 operator * (double f, const P3& a) { P3 rtn = a; return rtn *= f; }
443  inline P3 operator / (const P3& a, double f) { P3 rtn = a; return rtn /= f; }
445 
446 
447 
448 
449 
450 
451 
452 
453 }
Definition: Vectors3.h:34
double deltaR_eta(const P3 &v) const
Difference in pseudorapidity-based R between two vectors.
Definition: Vectors3.h:305
P3 & setThetaPhiP(double theta, double phi, double p)
Definition: Vectors3.h:192
double rho2() const
Get the spatial 3-vector |px^2 + py^2|.
Definition: Vectors3.h:261
P3(double px, double py, double pz)
Constructor from Cartesian/Minkowski coordinates.
Definition: Vectors3.h:53
double deltaR2_eta(const P3 &v) const
Difference in rapidity between two vectors.
Definition: Vectors3.h:303
double pT2() const
Get the transverse momentum squared (same as rho2)
Definition: Vectors3.h:267
P3 & setThetaPhiPt(double theta, double phi, double pt)
Definition: Vectors3.h:215
P3 & setXY(double px, double py)
set only transverse components
Definition: Vectors3.h:149
P3 & setP(double px, double py, double pz)
Set the p coordinates and mass simultaneously.
Definition: Vectors3.h:138
P3 & setPx(double px)
Set the px coordinate.
Definition: Vectors3.h:119
double angleTo(const P3 &v) const
Spatial angle to another P4 vector.
Definition: Vectors3.h:296
double pz() const
Get pz.
Definition: Vectors3.h:246
double px() const
Get px.
Definition: Vectors3.h:238
P3()
Default constructor of a null vector.
Definition: Vectors3.h:49
P3 & setEtaPhiPt(double eta, double phi, double pt)
Definition: Vectors3.h:174
double Z() const
Get pz^2.
Definition: Vectors3.h:252
double abseta() const
Get the spatial vector absolute pseudorapidity.
Definition: Vectors3.h:280
double dot3(const P3 &v) const
Spatial dot product.
Definition: Vectors3.h:291
double pT() const
Get the transverse momentum (same as rho)
Definition: Vectors3.h:269
double py() const
Get py.
Definition: Vectors3.h:242
P3 & setEtaPhiP(double eta, double phi, double P)
Definition: Vectors3.h:159
double deltaPhi(const P3 &v) const
Difference in phi between two vectors.
Definition: Vectors3.h:299
static P3 mkEtaPhiP(double eta, double phi, double P)
Make a vector from (eta,phi,p) coordinates.
Definition: Vectors3.h:92
double phi() const
Get the spatial phi.
Definition: Vectors3.h:274
static P3 mkThetaPhiPt(double theta, double phi, double pt)
Make a vector from (theta,phi,pT) coordinates and the mass.
Definition: Vectors3.h:107
static P3 mkThetaPhiP(double theta, double phi, double P)
Make a vector from (theta,phi,energy) coordinates and the mass.
Definition: Vectors3.h:102
double py2() const
Get py^2.
Definition: Vectors3.h:240
double p() const
Get the spatial 3-vector |p|.
Definition: Vectors3.h:259
P3 & setPy(double py)
Set the py coordinate.
Definition: Vectors3.h:125
double pz2() const
Get pz^2.
Definition: Vectors3.h:244
double deltaEta(const P3 &v) const
Difference in pseudorapidity between two vectors.
Definition: Vectors3.h:301
P3(const P3 &v)
Copy constructor.
Definition: Vectors3.h:58
P3 Cross(const P3 &v) const
Difference in rapidity-based R^2 between two vectors.
Definition: Vectors3.h:309
double theta() const
Get the spatial theta.
Definition: Vectors3.h:276
P3 & SetXYZ(double px, double py, double pz)
Alias for setP.
Definition: Vectors3.h:144
double Y() const
Get py^2.
Definition: Vectors3.h:250
double eta() const
Get the spatial vector pseudorapidity.
Definition: Vectors3.h:278
static P3 mkXYZ(double px, double py, double pz)
Make a vector from (px,py,pz,E) coordinates.
Definition: Vectors3.h:83
P3 & setPz(double pz)
Set the pz coordinate.
Definition: Vectors3.h:131
P3 & operator=(const P3 &v)
Copy assignment operator.
Definition: Vectors3.h:62
static P3 mkEtaPhiPt(double eta, double phi, double pt)
Make a vector from (eta,phi,pT) coordinates.
Definition: Vectors3.h:97
double px2() const
Get px^2.
Definition: Vectors3.h:236
void clear()
Set the components to zero.
Definition: Vectors3.h:70
double rho() const
Get the spatial 3-vector sqrt|px^2 + py^2|.
Definition: Vectors3.h:264
Modified by Mark Goodsell goodsell@lpthe.jussieu.fr
Definition: ATLAS_SUSY_2018_16.cc:27
std::string to_str(const P4 &p4)
Make a string representation of the vector.
Definition: Vectors.h:565
double deltaR2_eta(const P4 &a, const P4 &b)
Difference in pseudorapidity-based R^2 between two vectors.
Definition: Vectors.h:614
double deltaR_eta(const P4 &a, const P4 &b)
Difference in pseudorapidity-based R between two vectors.
Definition: Vectors.h:618
std::ostream & operator<<(std::ostream &ostr, const P4 &p4)
Write a string representation of the vector to the provided stream.
Definition: Vectors.h:572
double deltaEta(const P4 &a, const P4 &b)
Difference in pseudorapidity between two vectors.
Definition: Vectors.h:602
double deltaPhi(const P4 &a, const P4 &b)
Difference in phi between two vectors.
Definition: Vectors.h:596
constexpr std::enable_if< std::is_arithmetic< N1 >::value, N1 >::type sqr(const N1 val)
Convenience function for squaring (better than repeating long expressions/calcs or using intermediate...
Definition: MathUtils.h:45
double Dot(const P3 &a, const P3 &b)
Convenience "external" functions.
Definition: Vectors3.h:399
double angle(const P4 &a, const P4 &b)
Angle between two vectors.
Definition: Vectors.h:590