Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
CylindricalEta3D.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 MathLib Team and *
7  * FNAL LCG ROOT MathLib Team *
8  * *
9  * *
10  **********************************************************************/
11 
12 // Header file for class CylindricalEta3D
13 //
14 // Created by: Lorenzo Moneta at Mon May 30 11:58:46 2005
15 // Major revamp: M. Fischler at Fri Jun 10 2005
16 //
17 // Last update: $Id$
18 
19 //
20 #ifndef ROOT_Math_GenVector_CylindricalEta3D
21 #define ROOT_Math_GenVector_CylindricalEta3D 1
22 
23 #include "Math/Math.h"
24 
25 #include "Math/GenVector/etaMax.h"
26 
27 
28 #include <limits>
29 #include <cmath>
30 
31 #include "Math/Math.h"
32 
33 
34 namespace ROOT {
35 
36 namespace Math {
37 
38 //__________________________________________________________________________________________
39  /**
40  Class describing a cylindrical coordinate system based on eta (pseudorapidity) instead of z.
41  The base coordinates are rho (transverse component) , eta and phi
42  Phi is restricted to be in the range [-PI,PI)
43 
44  @ingroup GenVector
45  */
46 
47 template <class T>
48 class CylindricalEta3D {
49 
50 public :
51 
52  typedef T Scalar;
53 
54  /**
55  Default constructor with rho=eta=phi=0
56  */
57  CylindricalEta3D() : fRho(0), fEta(0), fPhi(0) { }
58 
59  /**
60  Construct from rho eta and phi values
61  */
62  CylindricalEta3D(Scalar rho, Scalar eta, Scalar phi) :
63  fRho(rho), fEta(eta), fPhi(phi) { Restrict(); }
64 
65  /**
66  Construct from any Vector or coordinate system implementing
67  Rho(), Eta() and Phi()
68  */
69  template <class CoordSystem >
70  explicit CylindricalEta3D( const CoordSystem & v ) :
71  fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() )
72  {
73  static Scalar bigEta = Scalar(-0.3) * log(std::numeric_limits<Scalar>::epsilon());
74  if (std::fabs(fEta) > bigEta) {
75  // This gives a small absolute adjustment in rho,
76  // which, for large eta, results in a significant
77  // improvement in the faithfullness of reproducing z.
78  fRho *= v.Z() / Z();
79  }
80  }
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  // re-implement them ( there is no no need to have them with g++4)
84 
85  /**
86  copy constructor
87  */
88  CylindricalEta3D(const CylindricalEta3D & v) :
89  fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() ) { }
90 
91  /**
92  assignment operator
93  */
94  CylindricalEta3D & operator= (const CylindricalEta3D & v) {
95  fRho = v.Rho();
96  fEta = v.Eta();
97  fPhi = v.Phi();
98  return *this;
99  }
100 
101  /**
102  Set internal data based on an array of 3 Scalar numbers
103  */
104  void SetCoordinates( const Scalar src[] )
105  { fRho=src[0]; fEta=src[1]; fPhi=src[2]; Restrict(); }
106 
107  /**
108  get internal data into an array of 3 Scalar numbers
109  */
110  void GetCoordinates( Scalar dest[] ) const
111  { dest[0] = fRho; dest[1] = fEta; dest[2] = fPhi; }
112 
113  /**
114  Set internal data based on 3 Scalar numbers
115  */
116  void SetCoordinates(Scalar rho, Scalar eta, Scalar phi)
117  { fRho=rho; fEta=eta; fPhi=phi; Restrict(); }
118 
119  /**
120  get internal data into 3 Scalar numbers
121  */
122  void GetCoordinates(Scalar& rho, Scalar& eta, Scalar& phi) const
123  {rho=fRho; eta=fEta; phi=fPhi;}
124 
125 private:
126  inline static Scalar pi() { return M_PI; }
127  inline void Restrict() {
128  if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - floor(fPhi / (2 * pi()) + .5) * 2 * pi();
129  return;
130  }
131 public:
132 
133  // accessors
134 
135  T Rho() const { return fRho; }
136  T Eta() const { return fEta; }
137  T Phi() const { return fPhi; }
138  T X() const { return fRho * cos(fPhi); }
139  T Y() const { return fRho * sin(fPhi); }
140  T Z() const
141  {
142  return fRho > 0 ? fRho * sinh(fEta) : fEta == 0 ? 0 : fEta > 0 ? fEta - etaMax<T>() : fEta + etaMax<T>();
143  }
144  T R() const
145  {
146  return fRho > 0 ? fRho * cosh(fEta)
147  : fEta > etaMax<T>() ? fEta - etaMax<T>() : fEta < -etaMax<T>() ? -fEta - etaMax<T>() : 0;
148  }
149  T Mag2() const
150  {
151  const Scalar r = R();
152  return r * r;
153  }
154  T Perp2() const { return fRho*fRho; }
155  T Theta() const { return fRho > 0 ? 2 * atan(exp(-fEta)) : (fEta >= 0 ? 0 : pi()); }
156 
157  // setters (only for data members)
158 
159 
160  /**
161  set the rho coordinate value keeping eta and phi constant
162  */
163  void SetRho(T rho) {
164  fRho = rho;
165  }
166 
167  /**
168  set the eta coordinate value keeping rho and phi constant
169  */
170  void SetEta(T eta) {
171  fEta = eta;
172  }
173 
174  /**
175  set the phi coordinate value keeping rho and eta constant
176  */
177  void SetPhi(T phi) {
178  fPhi = phi;
179  Restrict();
180  }
181 
182  /**
183  set all values using cartesian coordinates
184  */
185  void SetXYZ(Scalar x, Scalar y, Scalar z);
186 
187 
188  /**
189  scale by a scalar quantity a --
190  for cylindrical eta coords, as long as a >= 0, only rho changes!
191  */
192  void Scale (T a) {
193  if (a < 0) {
194  Negate();
195  a = -a;
196  }
197  // angles do not change when scaling by a positive quantity
198  if (fRho > 0) {
199  fRho *= a;
200  } else if ( fEta > etaMax<T>() ) {
201  fEta = ( fEta-etaMax<T>())*a + etaMax<T>();
202  } else if ( fEta < -etaMax<T>() ) {
203  fEta = ( fEta+etaMax<T>())*a - etaMax<T>();
204  } // when rho==0 and eta is not above etaMax, vector represents 0
205  // and remains unchanged
206  }
207 
208  /**
209  negate the vector
210  */
211  void Negate ( ) {
212  fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
213  fEta = -fEta;
214  }
215 
216  // assignment operators
217  /**
218  generic assignment operator from any coordinate system
219  */
220  template <class CoordSystem >
221  CylindricalEta3D & operator= ( const CoordSystem & c ) {
222  fRho = c.Rho();
223  fEta = c.Eta();
224  fPhi = c.Phi();
225  return *this;
226  }
227 
228  /**
229  Exact component-by-component equality
230  Note: Peculiar representaions of the zero vector such as (0,1,0) will
231  not test as equal to one another.
232  */
233  bool operator==(const CylindricalEta3D & rhs) const {
234  return fRho == rhs.fRho && fEta == rhs.fEta && fPhi == rhs.fPhi;
235  }
236  bool operator!= (const CylindricalEta3D & rhs) const
237  {return !(operator==(rhs));}
238 
239 
240  // ============= Compatibility section ==================
241 
242  // The following make this coordinate system look enough like a CLHEP
243  // vector that an assignment member template can work with either
244  T x() const { return X();}
245  T y() const { return Y();}
246  T z() const { return Z(); }
247 
248  // ============= Specializations for improved speed ==================
249 
250  // (none)
251 
252 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
253 
254  // ====== Set member functions for coordinates in other systems =======
255 
256  void SetX(Scalar x);
257 
258  void SetY(Scalar y);
259 
260  void SetZ(Scalar z);
261 
262  void SetR(Scalar r);
263 
264  void SetTheta(Scalar theta);
265 
266 
267 #endif
268 
269 
270 private:
271  T fRho;
272  T fEta;
273  T fPhi;
274 
275 };
276 
277  } // end namespace Math
278 
279 } // end namespace ROOT
280 
281 
282 // move implementations here to avoid circle dependencies
283 
285 
286 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
288 #include "Math/GenVector/Polar3D.h"
289 #endif
290 
291 namespace ROOT {
292 
293  namespace Math {
294 
295 template <class T>
296 void CylindricalEta3D<T>::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
297  *this = Cartesian3D<Scalar>(xx, yy, zz);
298 }
299 
300 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
301 
302 
303  // ====== Set member functions for coordinates in other systems =======
304 
305 
306 template <class T>
307 void CylindricalEta3D<T>::SetX(Scalar xx) {
308  GenVector_exception e("CylindricalEta3D::SetX() is not supposed to be called");
309  throw e;
310  Cartesian3D<Scalar> v(*this); v.SetX(xx);
311  *this = CylindricalEta3D<Scalar>(v);
312 }
313 template <class T>
314 void CylindricalEta3D<T>::SetY(Scalar yy) {
315  GenVector_exception e("CylindricalEta3D::SetY() is not supposed to be called");
316  throw e;
317  Cartesian3D<Scalar> v(*this); v.SetY(yy);
318  *this = CylindricalEta3D<Scalar>(v);
319 }
320 template <class T>
321 void CylindricalEta3D<T>::SetZ(Scalar zz) {
322  GenVector_exception e("CylindricalEta3D::SetZ() is not supposed to be called");
323  throw e;
324  Cartesian3D<Scalar> v(*this); v.SetZ(zz);
325  *this = CylindricalEta3D<Scalar>(v);
326 }
327 template <class T>
328 void CylindricalEta3D<T>::SetR(Scalar r) {
329  GenVector_exception e("CylindricalEta3D::SetR() is not supposed to be called");
330  throw e;
331  Polar3D<Scalar> v(*this); v.SetR(r);
332  *this = CylindricalEta3D<Scalar>(v);
333 }
334 template <class T>
335 void CylindricalEta3D<T>::SetTheta(Scalar theta) {
336  GenVector_exception e("CylindricalEta3D::SetTheta() is not supposed to be called");
337  throw e;
338  Polar3D<Scalar> v(*this); v.SetTheta(theta);
339  *this = CylindricalEta3D<Scalar>(v);
340 }
341 
342 #endif
343 
344 
345  } // end namespace Math
346 
347 } // end namespace ROOT
348 
349 
350 
351 #endif /* ROOT_Math_GenVector_CylindricalEta3D */