Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
PtEtaPhiM4D.h
Go to the documentation of this file.
1// @(#)root/mathcore:$Id$
2// Authors: W. Brown, M. Fischler, L. Moneta 2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team *
7 * *
8 * *
9 **********************************************************************/
10
11// Header file for class PtEtaPhiM4D
12//
13// Created by: fischler at Wed Jul 21 2005
14// Similar to PtEtaPhiMSystem by moneta
15//
16// Last update: $Id$
17//
18#ifndef ROOT_MathX_GenVectorX_PtEtaPhiM4D
19#define ROOT_MathX_GenVectorX_PtEtaPhiM4D 1
20
21#include "Math/Math.h"
22
24
26
28
30
31using namespace ROOT::ROOT_MATH_ARCH;
32
33// #define TRACE_CE
34#ifdef TRACE_CE
35#include <iostream>
36#endif
37
38#include <cmath>
39
40namespace ROOT {
41
42namespace ROOT_MATH_ARCH {
43
44//__________________________________________________________________________________________
45/**
46 Class describing a 4D cylindrical coordinate system
47 using Pt , Phi, Eta and M (mass)
48 The metric used is (-,-,-,+).
49 Spacelike particles (M2 < 0) are described with negative mass values,
50 but in this case m2 must always be less than P2 to preserve a positive value of E2
51 Phi is restricted to be in the range [-PI,PI)
52
53 @ingroup GenVectorX
54
55 @see GenVectorX
56*/
57
58template <class ScalarType>
60
61public:
62 typedef ScalarType Scalar;
63
64 // --------- Constructors ---------------
65
66 /**
67 Default constructor gives zero 4-vector (with zero mass)
68 */
69 PtEtaPhiM4D() : fPt(0), fEta(0), fPhi(0), fM(0) {}
70
71 /**
72 Constructor from pt, eta, phi, mass values
73 */
74 PtEtaPhiM4D(Scalar pt, Scalar eta, Scalar phi, Scalar mass) : fPt(pt), fEta(eta), fPhi(phi), fM(mass)
75 {
77 if (fM < 0)
79 }
80
81 /**
82 Generic constructor from any 4D coordinate system implementing
83 Pt(), Eta(), Phi() and M()
84 */
85 template <class CoordSystem>
86 explicit PtEtaPhiM4D(const CoordSystem &c) : fPt(c.Pt()), fEta(c.Eta()), fPhi(c.Phi()), fM(c.M())
87 {
89 }
90
91 /**
92 Set internal data based on an array of 4 Scalar numbers
93 */
95 {
96 fPt = src[0];
97 fEta = src[1];
98 fPhi = src[2];
99 fM = src[3];
100 RestrictPhi();
101 if (fM < 0)
103 }
104
105 /**
106 get internal data into an array of 4 Scalar numbers
107 */
109 {
110 dest[0] = fPt;
111 dest[1] = fEta;
112 dest[2] = fPhi;
113 dest[3] = fM;
114 }
115
116 /**
117 Set internal data based on 4 Scalar numbers
118 */
120 {
121 fPt = pt;
122 fEta = eta;
123 fPhi = phi;
124 fM = mass;
125 RestrictPhi();
126 if (fM < 0)
128 }
129
130 /**
131 get internal data into 4 Scalar numbers
132 */
133 void GetCoordinates(Scalar &pt, Scalar &eta, Scalar &phi, Scalar &mass) const
134 {
135 pt = fPt;
136 eta = fEta;
137 phi = fPhi;
138 mass = fM;
139 }
140
141 // --------- Coordinates and Coordinate-like Scalar properties -------------
142
143 // 4-D Cylindrical eta coordinate accessors
144
145 Scalar Pt() const { return fPt; }
146 Scalar Eta() const { return fEta; }
147 Scalar Phi() const { return fPhi; }
148 /**
149 M() is the invariant mass;
150 in this coordinate system it can be negagative if set that way.
151 */
152 Scalar M() const { return fM; }
153 Scalar Mag() const { return M(); }
154
155 Scalar Perp() const { return Pt(); }
156 Scalar Rho() const { return Pt(); }
157
158 // other coordinate representation
159
160 Scalar Px() const { return fPt * math_cos(fPhi); }
161 Scalar X() const { return Px(); }
162 Scalar Py() const { return fPt * math_sin(fPhi); }
163 Scalar Y() const { return Py(); }
164 Scalar Pz() const
165 {
166 return fPt > 0 ? fPt * math_sinh(fEta)
167 : fEta == 0 ? 0
168 : fEta > 0 ? fEta - etaMax<Scalar>()
169 : fEta + etaMax<Scalar>();
170 }
171 Scalar Z() const { return Pz(); }
172
173 /**
174 magnitude of momentum
175 */
176 Scalar P() const
177 {
178 return fPt > 0 ? fPt * math_cosh(fEta)
181 : 0;
182 }
183 Scalar R() const { return P(); }
184
185 /**
186 squared magnitude of spatial components (momentum squared)
187 */
188 Scalar P2() const
189 {
190 const Scalar p = P();
191 return p * p;
192 }
193
194 /**
195 energy squared
196 */
197 Scalar E2() const
198 {
199 Scalar e2 = P2() + M2();
200 // avoid rounding error which can make E2 negative when M2 is negative
201 return e2 > 0 ? e2 : 0;
202 }
203
204 /**
205 Energy (timelike component of momentum-energy 4-vector)
206 */
207 Scalar E() const { return math_sqrt(E2()); }
208
209 Scalar T() const { return E(); }
210
211 /**
212 vector magnitude squared (or mass squared)
213 In case of negative mass (spacelike particles return negative values)
214 */
215 Scalar M2() const { return (fM >= 0) ? fM * fM : -fM * fM; }
216 Scalar Mag2() const { return M2(); }
217
218 /**
219 transverse spatial component squared
220 */
221 Scalar Pt2() const { return fPt * fPt; }
222 Scalar Perp2() const { return Pt2(); }
223
224 /**
225 transverse mass squared
226 */
227 Scalar Mt2() const { return M2() + fPt * fPt; }
228
229 /**
230 transverse mass - will be negative if Mt2() is negative
231 */
232 Scalar Mt() const
233 {
234 const Scalar mm = Mt2();
235 if (mm >= 0) {
236 return math_sqrt(mm);
237 } else {
238#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
239 GenVector_Throw("PtEtaPhiM4D::Mt() - Tachyonic:\n"
240 " Pz^2 > E^2 so the transverse mass would be imaginary");
241#endif
242 return -math_sqrt(-mm);
243 }
244 }
245
246 /**
247 transverse energy squared
248 */
249 Scalar Et2() const
250 {
251 // a bit faster than et * et
252 return 2. * E2() / (math_cosh(2 * fEta) + 1);
253 }
254
255 /**
256 transverse energy
257 */
258 Scalar Et() const { return E() / math_cosh(fEta); }
259
260private:
261 inline static Scalar pi() { return M_PI; }
262 inline void RestrictPhi()
263 {
264 if (fPhi <= -pi() || fPhi > pi())
265 fPhi = fPhi - math_floor(fPhi / (2 * pi()) + .5) * 2 * pi();
266 }
267 // restrict the value of negative mass to avoid unphysical negative E2 values
268 // M2 must be less than P2 for the tachionic particles - otherwise use positive values
269 inline void RestrictNegMass()
270 {
271 if (fM < 0) {
272 if (P2() - fM * fM < 0) {
273#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
274 GenVector_Throw("PtEtaPhiM4D::unphysical value of mass, set to closest physical value");
275#endif
276 fM = -P();
277 }
278 }
279 }
280
281public:
282 /**
283 polar angle
284 */
285 Scalar Theta() const { return (fPt > 0 ? Scalar(2) * math_atan(math_exp(-fEta)) : fEta >= 0 ? 0 : pi()); }
286
287 // --------- Set Coordinates of this system ---------------
288
289 /**
290 set Pt value
291 */
292 void SetPt(Scalar pt) { fPt = pt; }
293 /**
294 set eta value
295 */
296 void SetEta(Scalar eta) { fEta = eta; }
297 /**
298 set phi value
299 */
300 void SetPhi(Scalar phi)
301 {
302 fPhi = phi;
303 RestrictPhi();
304 }
305 /**
306 set M value
307 */
308 void SetM(Scalar mass)
309 {
310 fM = mass;
311 if (fM < 0)
313 }
314
315 /**
316 set values using cartesian coordinate system
317 */
318 void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e);
319
320 // ------ Manipulations -------------
321
322 /**
323 negate the 4-vector -- Note that the energy cannot be negate (would need an additional data member)
324 therefore negate will work only on the spatial components
325 One would need to use negate only with vectors having the energy as data members
326 */
327 void Negate()
328 {
329 fPhi = ((fPhi > 0) ? fPhi - pi() : fPhi + pi());
330 fEta = -fEta;
331#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
332 GenVector_Throw("PtEtaPhiM4D::Negate - cannot negate the energy - can negate only the spatial components");
333#endif
334 }
335
336 /**
337 Scale coordinate values by a scalar quantity a
338 */
340 {
341 if (a < 0) {
342 Negate();
343 a = -a;
344 }
345 fPt *= a;
346 fM *= a;
347 }
348
349 /**
350 Assignment from a generic coordinate system implementing
351 Pt(), Eta(), Phi() and M()
352 */
353 template <class CoordSystem>
354 PtEtaPhiM4D &operator=(const CoordSystem &c)
355 {
356 fPt = c.Pt();
357 fEta = c.Eta();
358 fPhi = c.Phi();
359 fM = c.M();
360 return *this;
361 }
362
363 /**
364 Exact equality
365 */
366 bool operator==(const PtEtaPhiM4D &rhs) const
367 {
368 return fPt == rhs.fPt && fEta == rhs.fEta && fPhi == rhs.fPhi && fM == rhs.fM;
369 }
370 bool operator!=(const PtEtaPhiM4D &rhs) const { return !(operator==(rhs)); }
371
372 // ============= Compatibility section ==================
373
374 // The following make this coordinate system look enough like a CLHEP
375 // vector that an assignment member template can work with either
376 Scalar x() const { return X(); }
377 Scalar y() const { return Y(); }
378 Scalar z() const { return Z(); }
379 Scalar t() const { return E(); }
380
381#if defined(__MAKECINT__) || defined(G__DICTIONARY)
382
383 // ====== Set member functions for coordinates in other systems =======
384
385 void SetPx(Scalar px);
386
387 void SetPy(Scalar py);
388
389 void SetPz(Scalar pz);
390
391 void SetE(Scalar t);
392
393#endif
394
395private:
396 ScalarType fPt;
397 ScalarType fEta;
398 ScalarType fPhi;
399 ScalarType fM;
400};
401
402} // end namespace ROOT_MATH_ARCH
403} // end namespace ROOT
404
405// move implementations here to avoid circle dependencies
407
408namespace ROOT {
409
410namespace ROOT_MATH_ARCH {
411
412template <class ScalarType>
414{
415 *this = PxPyPzE4D<Scalar>(px, py, pz, e);
416}
417
418#if defined(__MAKECINT__) || defined(G__DICTIONARY)
419#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
420
421// ====== Set member functions for coordinates in other systems =======
422
423template <class ScalarType>
425{
426 GenVector_exception e("PtEtaPhiM4D::SetPx() is not supposed to be called");
427 throw e;
428 PxPyPzE4D<Scalar> v(*this);
429 v.SetPx(px);
430 *this = PtEtaPhiM4D<Scalar>(v);
431}
432template <class ScalarType>
433void PtEtaPhiM4D<ScalarType>::SetPy(Scalar py)
434{
435 GenVector_exception e("PtEtaPhiM4D::SetPx() is not supposed to be called");
436 throw e;
437 PxPyPzE4D<Scalar> v(*this);
438 v.SetPy(py);
439 *this = PtEtaPhiM4D<Scalar>(v);
440}
441template <class ScalarType>
443{
444 GenVector_exception e("PtEtaPhiM4D::SetPx() is not supposed to be called");
445 throw e;
446 PxPyPzE4D<Scalar> v(*this);
447 v.SetPz(pz);
448 *this = PtEtaPhiM4D<Scalar>(v);
449}
450template <class ScalarType>
452{
453 GenVector_exception e("PtEtaPhiM4D::SetE() is not supposed to be called");
454 throw e;
455 PxPyPzE4D<Scalar> v(*this);
456 v.SetE(energy);
457 *this = PtEtaPhiM4D<Scalar>(v);
458}
459
460#endif // endif __MAKE__CINT || G__DICTIONARY
461#endif
462
463} // end namespace ROOT_MATH_ARCH
464
465} // end namespace ROOT
466
467#endif // ROOT_MathX_GenVectorX_PtEtaPhiM4D
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
#define M_PI
Definition Rotated.cxx:105
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
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 M (mass) The metric used ...
Definition PtEtaPhiM4D.h:59
PtEtaPhiM4D & operator=(const CoordSystem &c)
Assignment from a generic coordinate system implementing Pt(), Eta(), Phi() and M()
PtEtaPhiM4D(const CoordSystem &c)
Generic constructor from any 4D coordinate system implementing Pt(), Eta(), Phi() and M()
Definition PtEtaPhiM4D.h:86
Scalar Theta() const
polar angle
Scalar M2() const
vector magnitude squared (or mass squared) In case of negative mass (spacelike particles return negat...
Scalar E2() const
energy squared
Scalar Et() const
transverse energy
void SetPhi(Scalar phi)
set phi value
void SetCoordinates(const Scalar src[])
Set internal data based on an array of 4 Scalar numbers.
Definition PtEtaPhiM4D.h:94
void SetPt(Scalar pt)
set Pt value
Scalar P2() const
squared magnitude of spatial components (momentum squared)
Scalar Pt2() const
transverse spatial component squared
PtEtaPhiM4D()
Default constructor gives zero 4-vector (with zero mass)
Definition PtEtaPhiM4D.h:69
void Negate()
negate the 4-vector – Note that the energy cannot be negate (would need an additional data member) th...
Scalar Mt() const
transverse mass - will be negative if Mt2() is negative
void SetEta(Scalar eta)
set eta value
Scalar E() const
Energy (timelike component of momentum-energy 4-vector)
void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e)
set values using cartesian coordinate system
void SetCoordinates(Scalar pt, Scalar eta, Scalar phi, Scalar mass)
Set internal data based on 4 Scalar numbers.
bool operator==(const PtEtaPhiM4D &rhs) const
Exact equality.
void GetCoordinates(Scalar dest[]) const
get internal data into an array of 4 Scalar numbers
Scalar Mt2() const
transverse mass squared
PtEtaPhiM4D(Scalar pt, Scalar eta, Scalar phi, Scalar mass)
Constructor from pt, eta, phi, mass values.
Definition PtEtaPhiM4D.h:74
void GetCoordinates(Scalar &pt, Scalar &eta, Scalar &phi, Scalar &mass) const
get internal data into 4 Scalar numbers
Scalar P() const
magnitude of momentum
Scalar Et2() const
transverse energy squared
void SetM(Scalar mass)
set M value
void Scale(Scalar a)
Scale coordinate values by a scalar quantity a.
Scalar M() const
M() is the invariant mass; in this coordinate system it can be negagative if set that way.
bool operator!=(const PtEtaPhiM4D &rhs) const
TPaveText * pt
Scalar math_floor(Scalar x)
Scalar math_cos(Scalar x)
Scalar math_atan(Scalar x)
void GenVector_Throw(const char *)
function throwing exception, by creating internally a GenVector_exception only when needed
Scalar math_sqrt(Scalar x)
Scalar math_sinh(Scalar x)
Scalar math_exp(Scalar x)
Scalar math_cosh(Scalar x)
Scalar math_sin(Scalar x)