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