thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
LorentzVector.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // LorentzVector.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5 //
6 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef ThePEG_LorentzVector_H
10 #define ThePEG_LorentzVector_H
11 
19 #include "LorentzVector.fh"
20 #include "ThePEG/Utilities/Direction.h"
21 #include "ThePEG/Utilities/UnitIO.h"
22 #include "LorentzRotation.h"
23 #include "ThreeVector.h"
24 
26 #ifdef NDEBUG
27 #define ERROR_IF(condition,message) if (false) {}
28 #else
29 #define ERROR_IF(condition,message) \
30  if ( condition ) throw ThePEG::Exception( (message) , ThePEG::Exception::eventerror)
31 #endif
32 
33 namespace ThePEG {
34 
35 template <typename Value> class LorentzVector;
36 
43 template <typename Value> class LorentzVector
44 {
45 private:
47  using Value2 = decltype(sqr(std::declval<Value>()));
48 
49 public:
52  LorentzVector()
53  : theX(), theY(), theZ(), theT() {}
54 
55  LorentzVector(Value x, Value y, Value z, Value t)
56  : theX(x), theY(y), theZ(z), theT(t) {}
57 
58  LorentzVector(const ThreeVector<Value> & v, Value t)
59  : theX(v.x()), theY(v.y()), theZ(v.z()), theT(t) {}
60 
61  template<typename U>
63  : theX(v.x()), theY(v.y()), theZ(v.z()), theT(v.t()) {}
65 
67  template <typename ValueB>
69  setX(b.x());
70  setY(b.y());
71  setZ(b.z());
72  setT(b.t());
73  return *this;
74  }
75 
76 public:
78 
79  Value x() const { return theX; }
80  Value y() const { return theY; }
81  Value z() const { return theZ; }
82  Value t() const { return theT; }
83  Value e() const { return t(); }
85 
87 
88  void setX(Value x) { theX = x; }
89  void setY(Value y) { theY = y; }
90  void setZ(Value z) { theZ = z; }
91  void setT(Value t) { theT = t; }
92  void setE(Value e) { setT(e); }
94 
95 public:
98  return ThreeVector<Value>(x(),y(),z());
99  }
100 
102  operator ThreeVector<Value>() const { return vect(); }
103 
105  void setVect(const ThreeVector<Value> & p) {
106  theX = p.x();
107  theY = p.y();
108  theZ = p.z();
109  }
110 
111 public:
114  {
115  return LorentzVector<Value>(conj(x()),conj(y()),conj(z()),conj(t()));
116  }
117 
119  Value2 m2() const
120  {
121  return (t()-z())*(t()+z()) - sqr(x()) - sqr(y());
122  }
123 
125  Value2 m2(const LorentzVector<Value> & a) const {
126  Value tt(a.t()+t()),zz(a.z()+z());
127  return (tt-zz)*(tt+zz)-sqr(a.x()+x())-sqr(a.y()+y());
128  }
129 
131  Value m() const
132  {
133  Value2 tmp = m2();
134  return tmp < Value2() ? -Value(sqrt(-tmp)) : Value(sqrt(tmp));
135  }
136 
138  Value2 mt2() const { return (t()-z())*(t()+z()); }
139 
141  Value mt() const
142  {
143  Value2 tmp = mt2();
144  return tmp < Value2() ? -Value(sqrt(-tmp)) : Value(sqrt(tmp));
145  }
146 
148  Value2 perp2() const { return sqr(x()) + sqr(y()); }
149 
151  Value perp() const { return sqrt(perp2()); }
152 
157  template <typename U>
158  Value2 perp2(const ThreeVector<U> & p) const
159  {
160  return vect().perp2(p);
161  }
162 
167  template <typename U>
168  Value perp(const ThreeVector<U> & p) const
169  {
170  return vect().perp(p);
171  }
172 
174  Value2 et2() const
175  {
176  Value2 pt2 = vect().perp2();
177  return pt2 == Value2() ? Value2() : e()*e() * pt2/(pt2+z()*z());
178  }
179 
181  Value et() const
182  {
183  Value2 etet = et2();
184  return e() < Value() ? -sqrt(etet) : sqrt(etet);
185  }
186 
188  Value2 et2(const ThreeVector<double> & v) const
189  {
190  Value2 pt2 = vect().perp2(v);
191  Value pv = vect().dot(v.unit());
192  return pt2 == Value2() ? Value2() : e()*e() * pt2/(pt2+pv*pv);
193  }
194 
196  Value et(const ThreeVector<double> & v) const
197  {
198  Value2 etet = et2(v);
199  return e() < Value() ? -sqrt(etet) : sqrt(etet);
200  }
201 
203 
204  Value2 rho2() const { return sqr(x()) + sqr(y()) + sqr(z()); }
206 
208  Value rho() const { return sqrt(rho2()); }
209 
211  void setRho(Value newRho)
212  {
213  Value oldRho = rho();
214  if (oldRho == Value())
215  return;
216  double factor = newRho / oldRho;
217  setX(x()*factor);
218  setY(y()*factor);
219  setZ(z()*factor);
220  }
221 
223  double theta() const
224  {
225  assert(!(x() == Value() && y() == Value() && z() == Value()));
226  return atan2(perp(),z());
227  }
228 
230  double cosTheta() const
231  {
232  Value ptot = rho();
233  assert( ptot > Value() );
234  return z() / ptot;
235  }
236 
238  double phi() const {
239  return atan2(y(),x()) ;
240  }
242 
244  double eta() const {
245  Value m = rho();
246  if ( m == Value() ) return 0.0;
247  Value pt = max(Constants::epsilon*m, perp());
248  double rap = log((m + abs(z()))/pt);
249  return z() > ZERO? rap: -rap;
250  }
251 
253  double angle(const LorentzVector<Value> & w) const
254  {
255  return vect().angle(w.vect());
256  }
257 
259  double rapidity() const {
260  if ( z() == ZERO ) return 0.0;
261  ERROR_IF(t() <= ZERO, "Tried to take rapidity of negative-energy Lorentz vector");
262  Value pt = sqrt(max(sqr(t()*Constants::epsilon), perp2() + m2()));
263  double rap = log((t() + abs(z()))/pt);
264  return z() > ZERO? rap: -rap;
265  }
266 
268  double rapidity(const Axis & ref) const {
269  double r = ref.mag2();
270  ERROR_IF(r == 0,"A zero vector used as reference to LorentzVector rapidity");
271  Value vdotu = vect().dot(ref)/sqrt(r);
272  if ( vdotu == ZERO ) return 0.0;
273  ERROR_IF(t() <= ZERO, "Tried to take rapidity of negative-energy Lorentz vector");
274  Value pt = sqrt(max(sqr(t()*Constants::epsilon), perp2(ref) + m2()));
275  double rap = log((t() + abs(z()))/pt);
276  return z() > ZERO? rap: -rap;
277  }
278 
283  Boost boostVector() const {
284  if (t() == Value()) {
285  if (rho2() == Value2())
286  return Boost();
287  else
288  ERROR_IF(true,"boostVector computed for LorentzVector with t=0 -- infinite result");
289  }
290  // result will make analytic sense but is physically meaningless
291  ERROR_IF(m2() <= Value2(),"boostVector computed for a non-timelike LorentzVector");
292  return vect() * (1./t());
293  }
294 
300  {
301  return -boostVector();
302  }
303 
305  Value plus() const { return t() + z(); }
307  Value minus() const { return t() - z(); }
308 
310  bool isNear(const LorentzVector<Value> & w, double epsilon) const
311  {
312  Value2 limit = abs(vect().dot(w.vect()));
313  limit += 0.25 * sqr( t() + w.t() );
314  limit *= sqr(epsilon);
315  Value2 delta = (vect() - w.vect()).mag2();
316  delta += sqr( t() - w.t() );
317  return (delta <= limit);
318  }
319 
322  {
323  return *this = m.operator*(*this);
324  }
325 
328  {
329  return transform(m);
330  }
331 
333  template <typename U>
334  auto dot(const LorentzVector<U> & a) const -> decltype(this->t() * a.t())
335  {
336  return t() * a.t() - ( x() * a.x() + y() * a.y() + z() * a.z() );
337  }
338 
339 
340 public:
341 
354  boost(double bx, double by, double bz, double gamma=-1.)
355  {
356  const double b2 = bx*bx + by*by + bz*bz;
357  if ( b2 == 0.0 ) return *this;
358  if ( gamma < 0.0 ) {
359  gamma = 1.0 / sqrt(1.0 - b2);
360  }
361  const Value bp = bx*x() + by*y() + bz*z();
362  const double gamma2 = (gamma - 1.0)/b2;
363 
364  setX(x() + gamma2*bp*bx + gamma*bx*t());
365  setY(y() + gamma2*bp*by + gamma*by*t());
366  setZ(z() + gamma2*bp*bz + gamma*bz*t());
367  setT(gamma*(t() + bp));
368  return *this;
369  }
370 
381  LorentzVector<Value> & boost(Boost b, double gamma=-1.) {
382  return boost(b.x(), b.y(), b.z(),gamma);
383  }
384 
391  double sinphi = sin(phi);
392  double cosphi = cos(phi);
393  Value ty = y() * cosphi - z() * sinphi;
394  theZ = z() * cosphi + y() * sinphi;
395  theY = ty;
396  return *this;
397  }
398 
405  double sinphi = sin(phi);
406  double cosphi = cos(phi);
407  Value tz = z() * cosphi - x() * sinphi;
408  theX = x() * cosphi + z() * sinphi;
409  theZ = tz;
410  return *this;
411  }
412 
419  double sinphi = sin(phi);
420  double cosphi = cos(phi);
421  Value tx = x() * cosphi - y() * sinphi;
422  theY = y() * cosphi + x() * sinphi;
423  theX = tx;
424  return *this;
425  }
426 
430  LorentzVector<Value> & rotateUz (const Axis & axis) {
431  Axis ax = axis.unit();
432  double u1 = ax.x();
433  double u2 = ax.y();
434  double u3 = ax.z();
435  double up = u1*u1 + u2*u2;
436  if (up>0) {
437  up = sqrt(up);
438  Value px = x(), py = y(), pz = z();
439  setX( (u1*u3*px - u2*py)/up + u1*pz );
440  setY( (u2*u3*px + u1*py)/up + u2*pz );
441  setZ( -up*px + u3*pz );
442  }
443  else if (u3 < 0.) {
444  setX(-x());
445  setZ(-z());
446  }
447  return *this;
448  }
449 
455  template <typename U>
457  if (angle == 0.0)
458  return *this;
459  const U ll = axis.mag();
460  assert( ll > U() );
461 
462  const double sa = sin(angle), ca = cos(angle);
463  const double dx = axis.x()/ll, dy = axis.y()/ll, dz = axis.z()/ll;
464  const Value xx = x(), yy = y(), zz = z();
465 
466  setX((ca+(1-ca)*dx*dx) * xx
467  +((1-ca)*dx*dy-sa*dz) * yy
468  +((1-ca)*dx*dz+sa*dy) * zz
469  );
470  setY(((1-ca)*dy*dx+sa*dz) * xx
471  +(ca+(1-ca)*dy*dy) * yy
472  +((1-ca)*dy*dz-sa*dx) * zz
473  );
474  setZ(((1-ca)*dz*dx-sa*dy) * xx
475  +((1-ca)*dz*dy+sa*dx) * yy
476  +(ca+(1-ca)*dz*dz) * zz
477  );
478  return *this;
479  }
480 
481 
482 
483 
484 public:
486 
487  LorentzVector<Complex> & operator+=(const LorentzVector<complex<QtyDouble> > & a) {
488  theX += a.x();
489  theY += a.y();
490  theZ += a.z();
491  theT += a.t();
492  return *this;
493  }
494 
495  template <typename ValueB>
496  LorentzVector<Value> & operator+=(const LorentzVector<ValueB> & a) {
497  theX += a.x();
498  theY += a.y();
499  theZ += a.z();
500  theT += a.t();
501  return *this;
502  }
503 
504  LorentzVector<Complex> & operator-=(const LorentzVector<complex<QtyDouble> > & a) {
505  theX -= Complex(a.x());
506  theY -= Complex(a.y());
507  theZ -= Complex(a.z());
508  theT -= Complex(a.t());
509  return *this;
510  }
511 
512  template <typename ValueB>
513  LorentzVector<Value> & operator-=(const LorentzVector<ValueB> & a) {
514  theX -= a.x();
515  theY -= a.y();
516  theZ -= a.z();
517  theT -= a.t();
518  return *this;
519  }
520 
521  LorentzVector<Value> & operator*=(double a) {
522  theX *= a;
523  theY *= a;
524  theZ *= a;
525  theT *= a;
526  return *this;
527  }
528 
529  LorentzVector<Value> & operator/=(double a) {
530  theX /= a;
531  theY /= a;
532  theZ /= a;
533  theT /= a;
534  return *this;
535  }
537 
538 private:
540 
541  Value theX;
542  Value theY;
543  Value theZ;
544  Value theT;
546 };
547 
549 
550 template <typename Value>
552 operator/(const LorentzVector<Value> & v, Value a) {
553  return LorentzVector<double>(v.x()/a, v.y()/a, v.z()/a, v.t()/a);
554 }
555 
557 operator/(const LorentzVector<Complex> & v, Complex a) {
558  return LorentzVector<Complex>(v.x()/a, v.y()/a, v.z()/a, v.t()/a);
559 }
560 
561 template <typename Value>
562 inline LorentzVector<Value> operator-(const LorentzVector<Value> & v) {
563  return LorentzVector<Value>(-v.x(),-v.y(),-v.z(),-v.t());
564 }
565 
566 template <typename ValueA, typename ValueB>
568 operator+(LorentzVector<ValueA> a, const LorentzVector<ValueB> & b) {
569  return a += b;
570 }
571 
572 template <typename ValueA, typename ValueB>
574 operator-(LorentzVector<ValueA> a, const LorentzVector<ValueB> & b) {
575  return a -= b;
576 }
577 
578 template <typename Value>
580 operator*(const LorentzVector<Value> & a, double b) {
581  return LorentzVector<Value>(a.x()*b, a.y()*b, a.z()*b, a.t()*b);
582 }
583 
584 template <typename Value>
586 operator*(double b, LorentzVector<Value> a) {
587  return a *= b;
588 }
589 
590 template <typename ValueA, typename ValueB>
591 inline auto operator*(ValueB a, const LorentzVector<ValueA> & v)
592 -> LorentzVector<decltype(a*v.x())>
593 {
594  return {a*v.x(), a*v.y(), a*v.z(), a*v.t()};
595 }
596 
597 template <typename ValueA, typename ValueB>
598 inline auto operator*(const LorentzVector<ValueA> & v, ValueB b)
599 -> LorentzVector<decltype(b*v.x())>
600 {
601  return b*v;
602 }
603 
604 template <typename ValueA, typename ValueB>
605 inline auto operator/(const LorentzVector<ValueA> & v, ValueB b)
606 -> LorentzVector<decltype(v.x()/b)>
607 {
608  return {v.x()/b, v.y()/b, v.z()/b, v.t()/b};
609 }
611 
613 
614 template <typename ValueA, typename ValueB>
615 inline auto
616 operator*(const LorentzVector<ValueA> & a, const LorentzVector<ValueB> & b)
617 -> decltype(a.dot(b))
618 {
619  return a.dot(b);
620 }
621 
623 
625 template <typename Value>
626 inline bool
627 operator==(const LorentzVector<Value> & a, const LorentzVector<Value> & b) {
628  return a.x() == b.x() && a.y() == b.y() && a.z() == b.z() && a.t() == b.t();
629 }
630 
632 inline ostream & operator<< (ostream & os, const LorentzVector<double> & v) {
633  return os << "(" << v.x() << "," << v.y() << "," << v.z()
634  << ";" << v.t() << ")";
635 }
636 
639 template <typename Value>
640 inline Value dirPlus(const LorentzVector<Value> & p) {
641  return Direction<0>::pos()? p.plus(): p.minus();
642 }
643 
646 template <typename Value>
647 inline Value dirMinus(const LorentzVector<Value> & p) {
648  return Direction<0>::neg()? p.plus(): p.minus();
649 }
650 
653 template <typename Value>
654 inline Value dirZ(const LorentzVector<Value> & p) {
655  return Direction<0>::dir()*p.z();
656 }
657 
660 template <typename Value>
661 inline double dirTheta(const LorentzVector<Value> & p) {
662  return Direction<0>::pos()? p.theta(): Constants::pi - p.theta();
663 }
664 
667 template <typename Value>
668 inline double dirCosTheta(const LorentzVector<Value> & p) {
669  return Direction<0>::pos()? p.cosTheta(): -p.cosTheta();
670 }
671 
674 template <typename Value>
677  if ( Direction<0>::neg() ) b.setZ(-b.z());
678  return b;
679 }
680 
683 template <typename Value>
685 lightCone(Value plus, Value minus, Value x, Value y) {
686  LorentzVector<Value> r(x, y, 0.5*(plus-minus), 0.5*(plus+minus));
687  return r;
688 }
689 
691 template <typename Value>
693 lightCone(Value plus, Value minus) {
694  // g++-3.3 has a problem with using Value() directly
695  // gcc-bug c++/3650, fixed in 3.4
696  static const Value zero = Value();
697  LorentzVector<Value> r(zero, zero,
698  0.5*(plus-minus), 0.5*(plus+minus));
699  return r;
700 }
701 
702 }
703 
704 
705 // delayed header inclusion to break inclusion loop:
706 // LorentzVec -> Transverse -> Lorentz5Vec -> LorentzVec
707 #include "Transverse.h"
708 
709 
710 
711 namespace ThePEG {
712 
715 template <typename Value>
718  LorentzVector<Value> r(pt.x(), pt.y(), 0.5*(plus-minus), 0.5*(plus+minus));
719  return r;
720 }
721 
725 template <typename Value>
727 lightConeDir(Value plus, Value minus,
728  Value x = Value(), Value y = Value()) {
729  LorentzVector<Value> r(x, y, Direction<0>::dir()*0.5*(plus - minus),
730  0.5*(plus + minus));
731  return r;
732 }
733 
737 template <typename Value>
739 lightConeDir(Value plus, Value minus, Transverse<Value> pt) {
740  LorentzVector<Value> r(pt.x(), pt.y(), Direction<0>::dir()*0.5*(plus - minus),
741  0.5*(plus + minus));
742  return r;
743 
744 }
745 
747 template <typename OStream, typename UnitT, typename Value>
748 void ounitstream(OStream & os, const LorentzVector<Value> & p, UnitT & u) {
749  os << ounit(p.x(), u) << ounit(p.y(), u) << ounit(p.z(), u)
750  << ounit(p.e(), u);
751 }
752 
754 template <typename IStream, typename UnitT, typename Value>
755 void iunitstream(IStream & is, LorentzVector<Value> & p, UnitT & u) {
756  Value x, y, z, e;
757  is >> iunit(x, u) >> iunit(y, u) >> iunit(z, u) >> iunit(e, u);
758  p = LorentzVector<Value>(x, y, z, e);
759 }
760 
761 
762 }
763 
764 #undef ERROR_IF
765 #endif /* ThePEG_LorentzVector_H */
LorentzVector< Value > & rotateUz(const Axis &axis)
Rotate the reference frame to a new z-axis.
double theta() const
Polar angle.
A 4-component Lorentz vector.
Definition: LorentzVector.h:35
LorentzVector< Value > & boost(Boost b, double gamma=-1.)
Apply boost.
#define ERROR_IF(condition, message)
Debug helper function.
Definition: LorentzVector.h:29
void setRho(Value newRho)
Set new radius.
static Dir dir()
Return the direction.
Definition: Direction.h:127
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition: Complex.h:23
LorentzVector< Value > lightConeDir(Value plus, Value minus, Value x=Value(), Value y=Value())
Create a LorentzVector giving its light-cone and transverse components.
Value m() const
Magnitude (signed) .
double rapidity(const Axis &ref) const
Rapidity with respect to another vector.
Value mag() const
Magnitude .
Definition: ThreeVector.h:74
auto dot(const LorentzVector< U > &a) const -> decltype(this->t() *a.t())
Dot product with metric .
Value rho() const
Radius.
Value2 rho2() const
Radius squared.
void ounitstream(OStream &os, const vector< T, Alloc > &v, UT &u)
Ouput a vector of objects with the specified unit.
Definition: Containers.h:275
LorentzVector< Value > lightCone(Value plus, Value minus, Value x, Value y)
Create a LorentzVector giving its light-cone and transverse components.
LorentzVector< Value > & operator=(const LorentzVector< ValueB > &b)
Assignment operator.
Definition: LorentzVector.h:68
double eta() const
Pseudorapidity of spatial part.
Value perp() const
Transverse component of the spatial vector .
A 3-component vector.
Definition: ThreeVector.h:34
Value2 mag2() const
Squared magnitude .
Definition: ThreeVector.h:71
LorentzVector< Value > & operator*=(const SpinOneLorentzRotation &m)
Rotate the vector. Resets .
constexpr double pi
Good old .
Definition: Constants.h:54
constexpr auto sqr(const T &x) -> decltype(x *x)
The square function should really have been included in the standard C++ library. ...
Definition: ThePEG.h:117
double dirTheta(const LorentzVector< Value > &p)
Return the polar angle wrt.
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
Value2 perp2() const
Squared transverse component of the spatial vector .
LorentzVector< Value > & boost(double bx, double by, double bz, double gamma=-1.)
Apply boost.
constexpr double epsilon
The smallest non-zero double.
Definition: Constants.h:63
double dirCosTheta(const LorentzVector< Value > &p)
Return the cosine of the polar angle wrt.
void iunitstream(IStream &is, vector< T, Alloc > &v, UT &u)
Input a vector of objects with the specified unit.
Definition: Containers.h:289
LorentzVector< Value > & rotateY(double phi)
Apply rotation around the y-axis.
static bool pos()
Return true if the direction is positive.
Definition: Direction.h:113
double phi() const
Azimuthal angle.
Boost boostVector() const
Boost from reference frame into this vector&#39;s rest frame: .
LorentzVector< Value > & rotateX(double phi)
Apply rotation around the x-axis.
Value x() const
The x-component.
Definition: Transverse.h:174
decltype(sqr(std::declval< complex< double > >())) Value2
Value squared.
Definition: LorentzVector.h:47
Value plus() const
Returns the positive light-cone component .
contains the ThreeVector class.
The SpinOneLorentzRotation class is ...
OUnit< T, UT > ounit(const T &t, const UT &ut)
Helper function creating a OUnit object given an object and a unit.
Definition: UnitIO.h:84
static bool neg()
Return true if the direction is negative (reversed).
Definition: Direction.h:120
Value y() const
The y-component.
Definition: Transverse.h:179
ThreeVector< double > unit() const
Parallel vector with unit length.
Definition: ThreeVector.h:139
LorentzVector< Value > & rotate(double angle, const ThreeVector< U > &axis)
Apply a rotation.
Value dirZ(const LorentzVector< Value > &p)
Return the component along the positive z-axis.
Value mt() const
Transverse mass (signed) .
Transverse represents the transverse components of a LorentzVector.
Definition: Transverse.h:30
Boost findBoostToCM() const
Boost from reference frame into this vector&#39;s rest frame: .
LorentzVector< Value > & rotateZ(double phi)
Apply rotation around the z-axis.
bool isNear(const LorentzVector< Value > &w, double epsilon) const
Are two vectors nearby, using Euclidean measure ?
double cosTheta() const
Cosine of the polar angle.
Value2 mt2() const
Transverse mass squared .
Value et(const ThreeVector< double > &v) const
Transverse energy with respect to the given axis (signed).
double rapidity() const
Rapidity .
ThreeVector< Value > vect() const
Access to the 3-component part.
Definition: LorentzVector.h:97
Value2 m2(const LorentzVector< Value > &a) const
Squared magnitude with another vector.
Value2 et2() const
Transverse energy squared.
void setVect(const ThreeVector< Value > &p)
Set the 3-component part.
Value dirMinus(const LorentzVector< Value > &p)
Return the negative light-cone component.
ThreeVector< Value > dirBoostVector(const LorentzVector< Value > &p)
Get the boost vector for the LorentzVector.
A Direction object can be used to specify that some following operations should be assumed to be perf...
Definition: Direction.h:41
Value2 m2() const
Squared magnitude .
LorentzVector< Value > conjugate() const
The complex conjugate vector.
Value2 et2(const ThreeVector< double > &v) const
Transverse energy squared with respect to the given axis.
Value perp(const ThreeVector< U > &p) const
Transverse component of the spatial vector with respect to the given axis.
Value dirPlus(const LorentzVector< Value > &p)
Return the positive light-cone component.
Value2 perp2(const ThreeVector< U > &p) const
Squared transverse component of the spatial vector with respect to the given axis.
LorentzVector< Value > & transform(const SpinOneLorentzRotation &m)
Rotate the vector. Resets .
double angle(const LorentzVector< Value > &w) const
Spatial angle with another vector.
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
Value minus() const
Returns the negative light-cone component .
Value et() const
Transverse energy (signed).
IUnit< T, UT > iunit(T &t, const UT &ut)
Helper function creating a IUnit object given an object and a unit.
Definition: UnitIO.h:91