ROOT   Reference Guide
PxPyPzM4D.h
Go to the documentation of this file.
1// @(#)root/mathcore:$Id: 464c29f33a8bbd8462a3e15b7e4c30c6f5b74a30$
2// Authors: W. Brown, M. Fischler, L. Moneta 2005
3
4/**********************************************************************
5* *
6* Copyright (c) 2005 , LCG ROOT MathLib Team *
7* *
8* *
9**********************************************************************/
10
11// Header file for class PxPyPzM4D
12//
13// Created by: fischler at Wed Jul 20 2005
14// (starting from PxPyPzM4D by moneta)
15//
16// Last update: $Id: 464c29f33a8bbd8462a3e15b7e4c30c6f5b74a30$
17//
18#ifndef ROOT_Math_GenVector_PxPyPzM4D
19#define ROOT_Math_GenVector_PxPyPzM4D 1
20
21#include "Math/GenVector/eta.h"
22
24
25
26#include <cmath>
27
28namespace ROOT {
29
30namespace Math {
31
32//__________________________________________________________________________________________
33/**
34 Class describing a 4D coordinate system
35 or momentum-energy vectors stored as (Px, Py, Pz, M).
36 This system is useful to describe ultra-relativistic particles
37 (like electrons at LHC) to avoid numerical errors evaluating the mass
38 when E >>> m
39 The metric used is (-,-,-,+)
40 Spacelike particles (M2 < 0) are described with negative mass values,
41 but in this case m2 must alwasy be less than P2 to preserve a positive value of E2
42
43 @ingroup GenVector
44
45 @sa Overview of the @ref GenVector "physics vector library"
46*/
47
48template <class ScalarType = double>
49class PxPyPzM4D {
50
51public :
52
53 typedef ScalarType Scalar;
54
55 // --------- Constructors ---------------
56
57 /**
58 Default constructor with x=y=z=m=0
59 */
60 PxPyPzM4D() : fX(0.0), fY(0.0), fZ(0.0), fM(0.0) { }
61
62
63 /**
64 Constructor from x, y , z , m values
65 */
67 fX(px), fY(py), fZ(pz), fM(m) {
68
69 if (fM < 0) RestrictNegMass();
70 }
71
72 /**
73 construct from any 4D coordinate system class
74 implementing X(), Y(), X() and M()
75 */
76 template <class CoordSystem>
77 explicit PxPyPzM4D(const CoordSystem & v) :
78 fX( v.X() ), fY( v.Y() ), fZ( v.Z() ), fM( v.M() )
79 { }
80
81 // for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
82 // so we decided to re-implement them ( there is no no need to have them with g++4)
83 /**
84 copy constructor
85 */
87 fX(v.fX), fY(v.fY), fZ(v.fZ), fM(v.fM) { }
88
89 /**
90 assignment operator
91 */
93 fX = v.fX;
94 fY = v.fY;
95 fZ = v.fZ;
96 fM = v.fM;
97 return *this;
98 }
99
100
101 /**
102 construct from any 4D coordinate system class
103 implementing X(), Y(), X() and M()
104 */
105 template <class AnyCoordSystem>
106 PxPyPzM4D & operator = (const AnyCoordSystem & v) {
107 fX = v.X();
108 fY = v.Y();
109 fZ = v.Z();
110 fM = v.M();
111 return *this;
112 }
113
114 /**
115 Set internal data based on an array of 4 Scalar numbers
116 */
117 void SetCoordinates( const Scalar src[] ) {
118 fX=src[0]; fY=src[1]; fZ=src[2]; fM=src[3];
119 if (fM < 0) RestrictNegMass();
120 }
121
122 /**
123 get internal data into an array of 4 Scalar numbers
124 */
125 void GetCoordinates( Scalar dest[] ) const
126 { dest[0] = fX; dest[1] = fY; dest[2] = fZ; dest[3] = fM; }
127
128 /**
129 Set internal data based on 4 Scalar numbers
130 */
132 fX=px; fY=py; fZ=pz; fM=m;
133 if (fM < 0) RestrictNegMass();
134 }
135
136 /**
137 get internal data into 4 Scalar numbers
138 */
139 void GetCoordinates(Scalar& px, Scalar& py, Scalar& pz, Scalar& m) const
140 { px=fX; py=fY; pz=fZ; m=fM;}
141
142 // --------- Coordinates and Coordinate-like Scalar properties -------------
143
144 // cartesian (Minkowski)coordinate accessors
145
146 Scalar Px() const { return fX;}
147 Scalar Py() const { return fY;}
148 Scalar Pz() const { return fZ;}
149 Scalar M() const { return fM; }
150
151 Scalar X() const { return fX;}
152 Scalar Y() const { return fY;}
153 Scalar Z() const { return fZ;}
154
155 // other coordinate representation
156 /**
157 Energy
158 */
159 Scalar E() const { using std::sqrt; return sqrt(E2()); }
160
161 Scalar T() const { return E();}
162
163 /**
164 squared magnitude of spatial components
165 */
166 Scalar P2() const { return fX*fX + fY*fY + fZ*fZ; }
167
168 /**
169 magnitude of spatial components (magnitude of 3-momentum)
170 */
171 Scalar P() const { using std::sqrt; return sqrt(P2()); }
172 Scalar R() const { return P(); }
173
174 /**
175 vector magnitude squared (or mass squared)
176 In case of negative mass (spacelike particles return negative values)
177 */
178 Scalar M2() const {
179 return ( fM >= 0 ) ? fM*fM : -fM*fM;
180 }
181 Scalar Mag2() const { return M2(); }
182
183 Scalar Mag() const { return M(); }
184
185 /**
186 energy squared
187 */
188 Scalar E2() const {
189 Scalar e2 = P2() + M2();
190 // protect against numerical errors when M2() is negative
191 return e2 > 0 ? e2 : 0;
192 }
193
194 /**
195 transverse spatial component squared
196 */
197 Scalar Pt2() const { return fX*fX + fY*fY;}
198 Scalar Perp2() const { return Pt2();}
199
200 /**
201 Transverse spatial component (P_perp or rho)
202 */
203 Scalar Pt() const { using std::sqrt; return sqrt(Perp2()); }
204 Scalar Perp() const { return Pt();}
205 Scalar Rho() const { return Pt();}
206
207 /**
208 transverse mass squared
209 */
210 Scalar Mt2() const { return E2() - fZ*fZ; }
211
212 /**
213 transverse mass
214 */
215 Scalar Mt() const {
216 const Scalar mm = Mt2();
217 if (mm >= 0) {
218 using std::sqrt;
219 return sqrt(mm);
220 } else {
221 GenVector::Throw ("PxPyPzM4D::Mt() - Tachyonic:\n"
222 " Pz^2 > E^2 so the transverse mass would be imaginary");
223 using std::sqrt;
224 return -sqrt(-mm);
225 }
226 }
227
228 /**
229 transverse energy squared
230 */
231 Scalar Et2() const { // is (E^2 * pt ^2) / p^2
232 // but it is faster to form p^2 from pt^2
233 Scalar pt2 = Pt2();
234 return pt2 == 0 ? 0 : E2() * pt2/( pt2 + fZ*fZ );
235 }
236
237 /**
238 transverse energy
239 */
240 Scalar Et() const {
241 const Scalar etet = Et2();
242 using std::sqrt;
243 return sqrt(etet);
244 }
245
246 /**
247 azimuthal angle
248 */
249 Scalar Phi() const { using std::atan2; return (fX == 0.0 && fY == 0.0) ? 0.0 : atan2(fY, fX); }
250
251 /**
252 polar angle
253 */
254 Scalar Theta() const { using std::atan2; return (fX == 0.0 && fY == 0.0 && fZ == 0.0) ? 0 : atan2(Pt(), fZ); }
255
256 /**
257 pseudorapidity
258 */
259 Scalar Eta() const {
260 return Impl::Eta_FromRhoZ ( Pt(), fZ);
261 }
262
263 // --------- Set Coordinates of this system ---------------
264
265
266 /**
267 set X value
268 */
269 void SetPx( Scalar px) {
270 fX = px;
271 }
272 /**
273 set Y value
274 */
275 void SetPy( Scalar py) {
276 fY = py;
277 }
278 /**
279 set Z value
280 */
281 void SetPz( Scalar pz) {
282 fZ = pz;
283 }
284 /**
285 set T value
286 */
287 void SetM( Scalar m) {
288 fM = m;
289 if (fM < 0) RestrictNegMass();
290 }
291
292 /**
293 set all values
294 */
295 void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e);
296
297 // ------ Manipulations -------------
298
299 /**
300 negate the 4-vector - Note that the energy cannot be negate (would need an additional data member)
301 therefore negate will work only on the spatial components.
302 One would need to use negate only with vectors having the energy as data members
303 */
304 void Negate( ) {
305 fX = -fX;
306 fY = -fY;
307 fZ = -fZ;
308 GenVector::Throw ("PxPyPzM4D::Negate - cannot negate the energy - can negate only the spatial components");
309 }
310
311 /**
312 scale coordinate values by a scalar quantity a
313 */
314 void Scale( const Scalar & a) {
315 fX *= a;
316 fY *= a;
317 fZ *= a;
318 fM *= a;
319 }
320
321
322 /**
323 Exact equality
324 */
325 bool operator == (const PxPyPzM4D & rhs) const {
326 return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ && fM == rhs.fM;
327 }
328 bool operator != (const PxPyPzM4D & rhs) const {return !(operator==(rhs));}
329
330
331 // ============= Compatibility section ==================
332
333 // The following make this coordinate system look enough like a CLHEP
334 // vector that an assignment member template can work with either
335 Scalar x() const { return X(); }
336 Scalar y() const { return Y(); }
337 Scalar z() const { return Z(); }
338 Scalar t() const { return E(); }
339
340
341
342#if defined(__MAKECINT__) || defined(G__DICTIONARY)
343
344 // ====== Set member functions for coordinates in other systems =======
345
346 void SetPt(Scalar pt);
347
348 void SetEta(Scalar eta);
349
350 void SetPhi(Scalar phi);
351
352 void SetE(Scalar t);
353
354#endif
355
356private:
357
358 // restrict the value of negative mass to avoid unphysical negative E2 values
359 // M2 must be less than P2 for the tachionic particles - otherwise use positive values
360 inline void RestrictNegMass() {
361 if ( fM >=0 ) return;
362 if ( P2() - fM*fM < 0 ) {
363 GenVector::Throw("PxPyPzM4D::unphysical value of mass, set to closest physical value");
364 fM = - P();
365 }
366 return;
367 }
368
369
370 /**
371 (contigous) data containing the coordinate values x,y,z,t
372 */
373
374 ScalarType fX;
375 ScalarType fY;
376 ScalarType fZ;
377 ScalarType fM;
378
379};
380
381} // end namespace Math
382} // end namespace ROOT
383
384
385// move implementations here to avoid circle dependencies
386
389
390namespace ROOT {
391
392namespace Math {
393
394template <class ScalarType>
396 *this = PxPyPzE4D<Scalar> (px, py, pz, e);
397}
398
399
400#if defined(__MAKECINT__) || defined(G__DICTIONARY)
401
402 // ====== Set member functions for coordinates in other systems =======
403
404 // ====== Set member functions for coordinates in other systems =======
405
406template <class ScalarType>
407inline void PxPyPzM4D<ScalarType>::SetPt(ScalarType pt) {
408 GenVector_exception e("PxPyPzM4D::SetPt() is not supposed to be called");
409 throw e;
410 PtEtaPhiE4D<ScalarType> v(*this); v.SetPt(pt); *this = PxPyPzM4D<ScalarType>(v);
411}
412template <class ScalarType>
413inline void PxPyPzM4D<ScalarType>::SetEta(ScalarType eta) {
414 GenVector_exception e("PxPyPzM4D::SetEta() is not supposed to be called");
415 throw e;
416 PtEtaPhiE4D<ScalarType> v(*this); v.SetEta(eta); *this = PxPyPzM4D<ScalarType>(v);
417}
418template <class ScalarType>
419inline void PxPyPzM4D<ScalarType>::SetPhi(ScalarType phi) {
420 GenVector_exception e("PxPyPzM4D::SetPhi() is not supposed to be called");
421 throw e;
422 PtEtaPhiE4D<ScalarType> v(*this); v.SetPhi(phi); *this = PxPyPzM4D<ScalarType>(v);
423}
424template <class ScalarType>
425inline void PxPyPzM4D<ScalarType>::SetE(ScalarType energy) {
426 GenVector_exception e("PxPyPzM4D::SetE() is not supposed to be called");
427 throw e;
428 PxPyPzE4D<ScalarType> v(*this); v.SetE(energy);
429 *this = PxPyPzM4D<ScalarType>(v);
430}
431
432
433#endif // endif __MAKE__CINT || G__DICTIONARY
434
435} // end namespace Math
436
437} // end namespace ROOT
438
439
440
441#endif // ROOT_Math_GenVector_PxPyPzM4D
#define e(i)
Definition: RSha256.hxx:103
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Class describing a 4D cylindrical coordinate system using Pt , Phi, Eta and E (or rho,...
Definition: PtEtaPhiE4D.h:54
Class describing a 4D cartesian coordinate system (x, y, z, t coordinates) or momentum-energy vectors...
Definition: PxPyPzE4D.h:44
Class describing a 4D coordinate system or momentum-energy vectors stored as (Px, Py,...
Definition: PxPyPzM4D.h:49
Scalar x() const
Definition: PxPyPzM4D.h:335
Scalar Pz() const
Definition: PxPyPzM4D.h:148
Scalar Theta() const
polar angle
Definition: PxPyPzM4D.h:254
Scalar Py() const
Definition: PxPyPzM4D.h:147
Scalar z() const
Definition: PxPyPzM4D.h:337
PxPyPzM4D(const PxPyPzM4D &v)
copy constructor
Definition: PxPyPzM4D.h:86
Scalar Px() const
Definition: PxPyPzM4D.h:146
PxPyPzM4D(const CoordSystem &v)
construct from any 4D coordinate system class implementing X(), Y(), X() and M()
Definition: PxPyPzM4D.h:77
Scalar y() const
Definition: PxPyPzM4D.h:336
Scalar Z() const
Definition: PxPyPzM4D.h:153
Scalar Et() const
transverse energy
Definition: PxPyPzM4D.h:240
PxPyPzM4D & operator=(const PxPyPzM4D &v)
assignment operator
Definition: PxPyPzM4D.h:92
Scalar E2() const
energy squared
Definition: PxPyPzM4D.h:188
ScalarType Scalar
Definition: PxPyPzM4D.h:53
void Scale(const Scalar &a)
scale coordinate values by a scalar quantity a
Definition: PxPyPzM4D.h:314
Scalar Perp() const
Definition: PxPyPzM4D.h:204
ScalarType fX
(contigous) data containing the coordinate values x,y,z,t
Definition: PxPyPzM4D.h:374
Scalar Mag() const
Definition: PxPyPzM4D.h:183
void GetCoordinates(Scalar &px, Scalar &py, Scalar &pz, Scalar &m) const
get internal data into 4 Scalar numbers
Definition: PxPyPzM4D.h:139
void SetPx(Scalar px)
set X value
Definition: PxPyPzM4D.h:269
PxPyPzM4D(Scalar px, Scalar py, Scalar pz, Scalar m)
Constructor from x, y , z , m values.
Definition: PxPyPzM4D.h:66
void SetCoordinates(const Scalar src[])
Set internal data based on an array of 4 Scalar numbers.
Definition: PxPyPzM4D.h:117
void Negate()
negate the 4-vector - Note that the energy cannot be negate (would need an additional data member) th...
Definition: PxPyPzM4D.h:304
Scalar M2() const
vector magnitude squared (or mass squared) In case of negative mass (spacelike particles return negat...
Definition: PxPyPzM4D.h:178
Scalar Mag2() const
Definition: PxPyPzM4D.h:181
Scalar P() const
magnitude of spatial components (magnitude of 3-momentum)
Definition: PxPyPzM4D.h:171
Scalar R() const
Definition: PxPyPzM4D.h:172
void SetPz(Scalar pz)
set Z value
Definition: PxPyPzM4D.h:281
Scalar Mt2() const
transverse mass squared
Definition: PxPyPzM4D.h:210
void SetCoordinates(Scalar px, Scalar py, Scalar pz, Scalar m)
Set internal data based on 4 Scalar numbers.
Definition: PxPyPzM4D.h:131
Scalar X() const
Definition: PxPyPzM4D.h:151
void GetCoordinates(Scalar dest[]) const
get internal data into an array of 4 Scalar numbers
Definition: PxPyPzM4D.h:125
Scalar M() const
Definition: PxPyPzM4D.h:149
Scalar Pt() const
Transverse spatial component (P_perp or rho)
Definition: PxPyPzM4D.h:203
bool operator==(const PxPyPzM4D &rhs) const
Exact equality.
Definition: PxPyPzM4D.h:325
Scalar E() const
Energy.
Definition: PxPyPzM4D.h:159
void SetPy(Scalar py)
set Y value
Definition: PxPyPzM4D.h:275
Scalar Mt() const
transverse mass
Definition: PxPyPzM4D.h:215
Scalar Y() const
Definition: PxPyPzM4D.h:152
Scalar Phi() const
azimuthal angle
Definition: PxPyPzM4D.h:249
Scalar P2() const
squared magnitude of spatial components
Definition: PxPyPzM4D.h:166
Scalar Pt2() const
transverse spatial component squared
Definition: PxPyPzM4D.h:197
bool operator!=(const PxPyPzM4D &rhs) const
Definition: PxPyPzM4D.h:328
Scalar Perp2() const
Definition: PxPyPzM4D.h:198
Scalar Et2() const
transverse energy squared
Definition: PxPyPzM4D.h:231
Scalar Rho() const
Definition: PxPyPzM4D.h:205
PxPyPzM4D()
Default constructor with x=y=z=m=0.
Definition: PxPyPzM4D.h:60
Scalar t() const
Definition: PxPyPzM4D.h:338
void SetM(Scalar m)
set T value
Definition: PxPyPzM4D.h:287
Scalar T() const
Definition: PxPyPzM4D.h:161
void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e)
set all values
Definition: PxPyPzM4D.h:395
Scalar Eta() const
pseudorapidity
Definition: PxPyPzM4D.h:259
TPaveText * pt
RVec< PromoteTypes< T0, T1 > > atan2(const T0 &x, const RVec< T1 > &v)
Definition: RVec.hxx:1805
Namespace for new Math classes and functions.
void Throw(const char *)
function throwing exception, by creating internally a GenVector_exception only when needed
Scalar Eta_FromRhoZ(Scalar rho, Scalar z)
Calculate eta given rho and zeta.
Definition: eta.h:48
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
Rotation3D::Scalar Scalar
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
static constexpr double mm
TMarker m
Definition: textangle.C:8
TArc a
Definition: textangle.C:12