ROOT logo
// @(#)root/mathcore:$Id: CylindricalEta3D.h 24923 2008-07-23 15:43:05Z moneta $
// Authors: W. Brown, M. Fischler, L. Moneta    2005  

 /**********************************************************************
  *                                                                    *
  * Copyright (c) 2005 , LCG ROOT MathLib Team  and                    *
  *                      FNAL LCG ROOT MathLib Team                    *
  *                                                                    *
  *                                                                    *
  **********************************************************************/

// Header file for class CylindricalEta3D
// 
// Created by: Lorenzo Moneta  at Mon May 30 11:58:46 2005
// Major revamp:  M. Fischler  at Fri Jun 10 2005
// 
// Last update: $Id: CylindricalEta3D.h 24923 2008-07-23 15:43:05Z moneta $

// 
#ifndef ROOT_Math_GenVector_CylindricalEta3D 
#define ROOT_Math_GenVector_CylindricalEta3D  1

#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif

#ifndef ROOT_Math_GenVector_etaMax
#include "Math/GenVector/etaMax.h"
#endif


#include <limits>

#include "Math/Math.h"
 

namespace ROOT { 

namespace Math { 

//__________________________________________________________________________________________
  /** 
      Class describing a cylindrical coordinate system based on eta (pseudorapidity) instead of z.  
      The base coordinates are rho (transverse component) , eta and phi
      Phi is restricted to be in the range [-PI,PI)
  
      @ingroup GenVector
  */ 

template <class T> 
class CylindricalEta3D { 

public : 

  typedef T Scalar;

  /**
     Default constructor with rho=eta=phi=0
   */
  CylindricalEta3D() : fRho(0), fEta(0), fPhi(0) {  }

  /**
     Construct from rho eta and phi values
   */
  CylindricalEta3D(Scalar rho, Scalar eta, Scalar phi) :  
  				fRho(rho), fEta(eta), fPhi(phi) { Restrict(); }

  /**
     Construct from any Vector or coordinate system implementing 
     Rho(), Eta() and Phi()
    */ 
  template <class CoordSystem > 
  explicit CylindricalEta3D( const CoordSystem & v ) : 
    	fRho(v.Rho() ),  fEta(v.Eta() ),  fPhi(v.Phi() )  
  {  
    static Scalar bigEta = 
    			-.3f *std::log(std::numeric_limits<Scalar>::epsilon());
    if ( std::fabs(fEta) > bigEta ) {
       fRho *= v.Z()/Z(); // This gives a small absolute adjustment in rho,
       // which, for large eta, results in a significant
       // improvement in the faithfullness of reproducing z.
    }
  } 

   // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower 
   // re-implement them ( there is no no need to have them with g++4)

   /**
      copy constructor
   */
   CylindricalEta3D(const CylindricalEta3D & v) :
      fRho(v.Rho() ),  fEta(v.Eta() ),  fPhi(v.Phi() )  {   } 

   /**
      assignment operator 
   */
   CylindricalEta3D & operator= (const CylindricalEta3D & v) { 
      fRho = v.Rho();  
      fEta = v.Eta(); 
      fPhi = v.Phi(); 
      return *this;
   } 

   /**
      Set internal data based on an array of 3 Scalar numbers
   */ 
   void SetCoordinates( const Scalar src[] ) 
   { fRho=src[0]; fEta=src[1]; fPhi=src[2]; Restrict(); }

   /**
      get internal data into an array of 3 Scalar numbers
   */ 
   void GetCoordinates( Scalar dest[] ) const 
   { dest[0] = fRho; dest[1] = fEta; dest[2] = fPhi; }

   /**
      Set internal data based on 3 Scalar numbers
   */ 
   void SetCoordinates(Scalar  rho, Scalar  eta, Scalar  phi) 
   { fRho=rho; fEta=eta; fPhi=phi; Restrict(); }

   /**
      get internal data into 3 Scalar numbers
   */ 
   void GetCoordinates(Scalar& rho, Scalar& eta, Scalar& phi) const 
   {rho=fRho; eta=fEta; phi=fPhi;}  				

private:
   inline static Scalar pi() { return M_PI; } 
   inline void Restrict() {
      if ( fPhi <= -pi() || fPhi > pi() ) 
         fPhi = fPhi - std::floor( fPhi/(2*pi()) +.5 ) * 2*pi();
      return;
   } 
public:
   
   // accessors
 
   T Rho()   const { return fRho; }
   T Eta()   const { return fEta; } 
   T Phi()   const { return fPhi; }
   T X()     const { return fRho*std::cos(fPhi); }
   T Y()     const { return fRho*std::sin(fPhi); }
   T Z()     const { return fRho >  0 ? fRho*std::sinh(fEta) : 
      fEta == 0 ? 0                    :
      fEta >  0 ? fEta - etaMax<T>()   :
      fEta + etaMax<T>()   ; }
   T R()     const { return fRho > 0          ? fRho*std::cosh(fEta) :
      fEta >  etaMax<T>() ?  fEta - etaMax<T>()   :
      fEta < -etaMax<T>() ? -fEta - etaMax<T>()   :
      0		   ; }
   T Mag2()  const { return R()*R();              }
   T Perp2() const { return fRho*fRho;            }
   T Theta() const { return  fRho >  0 ? 2* std::atan( std::exp( - fEta ) ) :
         (fEta >= 0 ? 0 : pi() );  }
 
   // setters (only for data members) 

  
   /** 
       set the rho coordinate value keeping eta and phi constant
   */ 
   void SetRho(T rho) { 
      fRho = rho;      
   }

   /** 
       set the eta coordinate value keeping rho and phi constant
   */ 
   void SetEta(T eta) { 
      fEta = eta;      
   }

   /** 
       set the phi coordinate value keeping rho and eta constant
   */ 
   void SetPhi(T phi) { 
      fPhi = phi;      
      Restrict();
   }

   /** 
       set all values using cartesian coordinates  
   */
   void SetXYZ(Scalar x, Scalar y, Scalar z); 


   /**
      scale by a scalar quantity a -- 
      for cylindrical eta coords, as long as a >= 0, only rho changes!
   */ 
   void Scale (T a) { 
      if (a < 0) {
         Negate();
         a = -a;
      }
      // angles do not change when scaling by a positive quantity
      if (fRho > 0) {
         fRho *= a;   
      } else if ( fEta >  etaMax<T>() ) {
         fEta =  ( fEta-etaMax<T>())*a + etaMax<T>();
      } else if ( fEta < -etaMax<T>() ) {  
         fEta =  ( fEta+etaMax<T>())*a - etaMax<T>();
      } // when rho==0 and eta is not above etaMax, vector represents 0 
      // and remains unchanged
   }

   /**
      negate the vector
   */ 
   void Negate ( ) { 
      fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi()  );
      fEta = -fEta;
   }

   // assignment operators
   /**
      generic assignment operator from any coordinate system 
   */ 
   template <class CoordSystem > 
   CylindricalEta3D & operator= ( const CoordSystem & c ) { 
      fRho = c.Rho();  
      fEta = c.Eta(); 
      fPhi = c.Phi(); 
      return *this;
   }

   /**
      Exact component-by-component equality 
      Note: Peculiar representaions of the zero vector such as (0,1,0) will
      not test as equal to one another.     
   */  
   bool operator==(const CylindricalEta3D & rhs) const {
      return fRho == rhs.fRho && fEta == rhs.fEta && fPhi == rhs.fPhi;
   }
   bool operator!= (const CylindricalEta3D & rhs) const 
   {return !(operator==(rhs));}
  

   // ============= Compatibility section ==================
  
   // The following make this coordinate system look enough like a CLHEP
   // vector that an assignment member template can work with either
   T x() const { return X();}
   T y() const { return Y();}
   T z() const { return Z(); } 
  
   // ============= Specializations for improved speed ==================

   // (none)

#if defined(__MAKECINT__) || defined(G__DICTIONARY) 

   // ====== Set member functions for coordinates in other systems =======

   void SetX(Scalar x); 

   void SetY(Scalar y); 
  
   void SetZ(Scalar z); 
  
   void SetR(Scalar r);
  
   void SetTheta(Scalar theta);  


#endif


private:
   T fRho;
   T fEta;
   T fPhi;

};

  } // end namespace Math

} // end namespace ROOT


// move implementations here to avoid circle dependencies

#ifndef ROOT_Math_Cartesian3D
#include "Math/GenVector/Cartesian3D.h"
#endif


#if defined(__MAKECINT__) || defined(G__DICTIONARY) 
#include "Math/GenVector/GenVector_exception.h"
#include "Math/GenVector/Polar3D.h"
#endif

namespace ROOT { 

  namespace Math { 

template <class T>  
void CylindricalEta3D<T>::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {  
   *this = Cartesian3D<Scalar>(xx, yy, zz);
}

#if defined(__MAKECINT__) || defined(G__DICTIONARY) 

     // ====== Set member functions for coordinates in other systems =======


template <class T>  
void CylindricalEta3D<T>::SetX(Scalar xx) {  
   GenVector_exception e("CylindricalEta3D::SetX() is not supposed to be called");
   throw e;
   Cartesian3D<Scalar> v(*this); v.SetX(xx); 
   *this = CylindricalEta3D<Scalar>(v);
}
template <class T>  
void CylindricalEta3D<T>::SetY(Scalar yy) {  
   GenVector_exception e("CylindricalEta3D::SetY() is not supposed to be called");
   throw e;
   Cartesian3D<Scalar> v(*this); v.SetY(yy); 
   *this = CylindricalEta3D<Scalar>(v);
}
template <class T>  
void CylindricalEta3D<T>::SetZ(Scalar zz) {  
   GenVector_exception e("CylindricalEta3D::SetZ() is not supposed to be called");
   throw e;
   Cartesian3D<Scalar> v(*this); v.SetZ(zz); 
   *this = CylindricalEta3D<Scalar>(v);
}
template <class T>  
void CylindricalEta3D<T>::SetR(Scalar r) {  
   GenVector_exception e("CylindricalEta3D::SetR() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetR(r); 
   *this = CylindricalEta3D<Scalar>(v);
}
template <class T>  
void CylindricalEta3D<T>::SetTheta(Scalar theta) {  
   GenVector_exception e("CylindricalEta3D::SetTheta() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetTheta(theta); 
   *this = CylindricalEta3D<Scalar>(v);
}

#endif


  } // end namespace Math
   
} // end namespace ROOT



#endif /* ROOT_Math_GenVector_CylindricalEta3D  */
 CylindricalEta3D.h:1
 CylindricalEta3D.h:2
 CylindricalEta3D.h:3
 CylindricalEta3D.h:4
 CylindricalEta3D.h:5
 CylindricalEta3D.h:6
 CylindricalEta3D.h:7
 CylindricalEta3D.h:8
 CylindricalEta3D.h:9
 CylindricalEta3D.h:10
 CylindricalEta3D.h:11
 CylindricalEta3D.h:12
 CylindricalEta3D.h:13
 CylindricalEta3D.h:14
 CylindricalEta3D.h:15
 CylindricalEta3D.h:16
 CylindricalEta3D.h:17
 CylindricalEta3D.h:18
 CylindricalEta3D.h:19
 CylindricalEta3D.h:20
 CylindricalEta3D.h:21
 CylindricalEta3D.h:22
 CylindricalEta3D.h:23
 CylindricalEta3D.h:24
 CylindricalEta3D.h:25
 CylindricalEta3D.h:26
 CylindricalEta3D.h:27
 CylindricalEta3D.h:28
 CylindricalEta3D.h:29
 CylindricalEta3D.h:30
 CylindricalEta3D.h:31
 CylindricalEta3D.h:32
 CylindricalEta3D.h:33
 CylindricalEta3D.h:34
 CylindricalEta3D.h:35
 CylindricalEta3D.h:36
 CylindricalEta3D.h:37
 CylindricalEta3D.h:38
 CylindricalEta3D.h:39
 CylindricalEta3D.h:40
 CylindricalEta3D.h:41
 CylindricalEta3D.h:42
 CylindricalEta3D.h:43
 CylindricalEta3D.h:44
 CylindricalEta3D.h:45
 CylindricalEta3D.h:46
 CylindricalEta3D.h:47
 CylindricalEta3D.h:48
 CylindricalEta3D.h:49
 CylindricalEta3D.h:50
 CylindricalEta3D.h:51
 CylindricalEta3D.h:52
 CylindricalEta3D.h:53
 CylindricalEta3D.h:54
 CylindricalEta3D.h:55
 CylindricalEta3D.h:56
 CylindricalEta3D.h:57
 CylindricalEta3D.h:58
 CylindricalEta3D.h:59
 CylindricalEta3D.h:60
 CylindricalEta3D.h:61
 CylindricalEta3D.h:62
 CylindricalEta3D.h:63
 CylindricalEta3D.h:64
 CylindricalEta3D.h:65
 CylindricalEta3D.h:66
 CylindricalEta3D.h:67
 CylindricalEta3D.h:68
 CylindricalEta3D.h:69
 CylindricalEta3D.h:70
 CylindricalEta3D.h:71
 CylindricalEta3D.h:72
 CylindricalEta3D.h:73
 CylindricalEta3D.h:74
 CylindricalEta3D.h:75
 CylindricalEta3D.h:76
 CylindricalEta3D.h:77
 CylindricalEta3D.h:78
 CylindricalEta3D.h:79
 CylindricalEta3D.h:80
 CylindricalEta3D.h:81
 CylindricalEta3D.h:82
 CylindricalEta3D.h:83
 CylindricalEta3D.h:84
 CylindricalEta3D.h:85
 CylindricalEta3D.h:86
 CylindricalEta3D.h:87
 CylindricalEta3D.h:88
 CylindricalEta3D.h:89
 CylindricalEta3D.h:90
 CylindricalEta3D.h:91
 CylindricalEta3D.h:92
 CylindricalEta3D.h:93
 CylindricalEta3D.h:94
 CylindricalEta3D.h:95
 CylindricalEta3D.h:96
 CylindricalEta3D.h:97
 CylindricalEta3D.h:98
 CylindricalEta3D.h:99
 CylindricalEta3D.h:100
 CylindricalEta3D.h:101
 CylindricalEta3D.h:102
 CylindricalEta3D.h:103
 CylindricalEta3D.h:104
 CylindricalEta3D.h:105
 CylindricalEta3D.h:106
 CylindricalEta3D.h:107
 CylindricalEta3D.h:108
 CylindricalEta3D.h:109
 CylindricalEta3D.h:110
 CylindricalEta3D.h:111
 CylindricalEta3D.h:112
 CylindricalEta3D.h:113
 CylindricalEta3D.h:114
 CylindricalEta3D.h:115
 CylindricalEta3D.h:116
 CylindricalEta3D.h:117
 CylindricalEta3D.h:118
 CylindricalEta3D.h:119
 CylindricalEta3D.h:120
 CylindricalEta3D.h:121
 CylindricalEta3D.h:122
 CylindricalEta3D.h:123
 CylindricalEta3D.h:124
 CylindricalEta3D.h:125
 CylindricalEta3D.h:126
 CylindricalEta3D.h:127
 CylindricalEta3D.h:128
 CylindricalEta3D.h:129
 CylindricalEta3D.h:130
 CylindricalEta3D.h:131
 CylindricalEta3D.h:132
 CylindricalEta3D.h:133
 CylindricalEta3D.h:134
 CylindricalEta3D.h:135
 CylindricalEta3D.h:136
 CylindricalEta3D.h:137
 CylindricalEta3D.h:138
 CylindricalEta3D.h:139
 CylindricalEta3D.h:140
 CylindricalEta3D.h:141
 CylindricalEta3D.h:142
 CylindricalEta3D.h:143
 CylindricalEta3D.h:144
 CylindricalEta3D.h:145
 CylindricalEta3D.h:146
 CylindricalEta3D.h:147
 CylindricalEta3D.h:148
 CylindricalEta3D.h:149
 CylindricalEta3D.h:150
 CylindricalEta3D.h:151
 CylindricalEta3D.h:152
 CylindricalEta3D.h:153
 CylindricalEta3D.h:154
 CylindricalEta3D.h:155
 CylindricalEta3D.h:156
 CylindricalEta3D.h:157
 CylindricalEta3D.h:158
 CylindricalEta3D.h:159
 CylindricalEta3D.h:160
 CylindricalEta3D.h:161
 CylindricalEta3D.h:162
 CylindricalEta3D.h:163
 CylindricalEta3D.h:164
 CylindricalEta3D.h:165
 CylindricalEta3D.h:166
 CylindricalEta3D.h:167
 CylindricalEta3D.h:168
 CylindricalEta3D.h:169
 CylindricalEta3D.h:170
 CylindricalEta3D.h:171
 CylindricalEta3D.h:172
 CylindricalEta3D.h:173
 CylindricalEta3D.h:174
 CylindricalEta3D.h:175
 CylindricalEta3D.h:176
 CylindricalEta3D.h:177
 CylindricalEta3D.h:178
 CylindricalEta3D.h:179
 CylindricalEta3D.h:180
 CylindricalEta3D.h:181
 CylindricalEta3D.h:182
 CylindricalEta3D.h:183
 CylindricalEta3D.h:184
 CylindricalEta3D.h:185
 CylindricalEta3D.h:186
 CylindricalEta3D.h:187
 CylindricalEta3D.h:188
 CylindricalEta3D.h:189
 CylindricalEta3D.h:190
 CylindricalEta3D.h:191
 CylindricalEta3D.h:192
 CylindricalEta3D.h:193
 CylindricalEta3D.h:194
 CylindricalEta3D.h:195
 CylindricalEta3D.h:196
 CylindricalEta3D.h:197
 CylindricalEta3D.h:198
 CylindricalEta3D.h:199
 CylindricalEta3D.h:200
 CylindricalEta3D.h:201
 CylindricalEta3D.h:202
 CylindricalEta3D.h:203
 CylindricalEta3D.h:204
 CylindricalEta3D.h:205
 CylindricalEta3D.h:206
 CylindricalEta3D.h:207
 CylindricalEta3D.h:208
 CylindricalEta3D.h:209
 CylindricalEta3D.h:210
 CylindricalEta3D.h:211
 CylindricalEta3D.h:212
 CylindricalEta3D.h:213
 CylindricalEta3D.h:214
 CylindricalEta3D.h:215
 CylindricalEta3D.h:216
 CylindricalEta3D.h:217
 CylindricalEta3D.h:218
 CylindricalEta3D.h:219
 CylindricalEta3D.h:220
 CylindricalEta3D.h:221
 CylindricalEta3D.h:222
 CylindricalEta3D.h:223
 CylindricalEta3D.h:224
 CylindricalEta3D.h:225
 CylindricalEta3D.h:226
 CylindricalEta3D.h:227
 CylindricalEta3D.h:228
 CylindricalEta3D.h:229
 CylindricalEta3D.h:230
 CylindricalEta3D.h:231
 CylindricalEta3D.h:232
 CylindricalEta3D.h:233
 CylindricalEta3D.h:234
 CylindricalEta3D.h:235
 CylindricalEta3D.h:236
 CylindricalEta3D.h:237
 CylindricalEta3D.h:238
 CylindricalEta3D.h:239
 CylindricalEta3D.h:240
 CylindricalEta3D.h:241
 CylindricalEta3D.h:242
 CylindricalEta3D.h:243
 CylindricalEta3D.h:244
 CylindricalEta3D.h:245
 CylindricalEta3D.h:246
 CylindricalEta3D.h:247
 CylindricalEta3D.h:248
 CylindricalEta3D.h:249
 CylindricalEta3D.h:250
 CylindricalEta3D.h:251
 CylindricalEta3D.h:252
 CylindricalEta3D.h:253
 CylindricalEta3D.h:254
 CylindricalEta3D.h:255
 CylindricalEta3D.h:256
 CylindricalEta3D.h:257
 CylindricalEta3D.h:258
 CylindricalEta3D.h:259
 CylindricalEta3D.h:260
 CylindricalEta3D.h:261
 CylindricalEta3D.h:262
 CylindricalEta3D.h:263
 CylindricalEta3D.h:264
 CylindricalEta3D.h:265
 CylindricalEta3D.h:266
 CylindricalEta3D.h:267
 CylindricalEta3D.h:268
 CylindricalEta3D.h:269
 CylindricalEta3D.h:270
 CylindricalEta3D.h:271
 CylindricalEta3D.h:272
 CylindricalEta3D.h:273
 CylindricalEta3D.h:274
 CylindricalEta3D.h:275
 CylindricalEta3D.h:276
 CylindricalEta3D.h:277
 CylindricalEta3D.h:278
 CylindricalEta3D.h:279
 CylindricalEta3D.h:280
 CylindricalEta3D.h:281
 CylindricalEta3D.h:282
 CylindricalEta3D.h:283
 CylindricalEta3D.h:284
 CylindricalEta3D.h:285
 CylindricalEta3D.h:286
 CylindricalEta3D.h:287
 CylindricalEta3D.h:288
 CylindricalEta3D.h:289
 CylindricalEta3D.h:290
 CylindricalEta3D.h:291
 CylindricalEta3D.h:292
 CylindricalEta3D.h:293
 CylindricalEta3D.h:294
 CylindricalEta3D.h:295
 CylindricalEta3D.h:296
 CylindricalEta3D.h:297
 CylindricalEta3D.h:298
 CylindricalEta3D.h:299
 CylindricalEta3D.h:300
 CylindricalEta3D.h:301
 CylindricalEta3D.h:302
 CylindricalEta3D.h:303
 CylindricalEta3D.h:304
 CylindricalEta3D.h:305
 CylindricalEta3D.h:306
 CylindricalEta3D.h:307
 CylindricalEta3D.h:308
 CylindricalEta3D.h:309
 CylindricalEta3D.h:310
 CylindricalEta3D.h:311
 CylindricalEta3D.h:312
 CylindricalEta3D.h:313
 CylindricalEta3D.h:314
 CylindricalEta3D.h:315
 CylindricalEta3D.h:316
 CylindricalEta3D.h:317
 CylindricalEta3D.h:318
 CylindricalEta3D.h:319
 CylindricalEta3D.h:320
 CylindricalEta3D.h:321
 CylindricalEta3D.h:322
 CylindricalEta3D.h:323
 CylindricalEta3D.h:324
 CylindricalEta3D.h:325
 CylindricalEta3D.h:326
 CylindricalEta3D.h:327
 CylindricalEta3D.h:328
 CylindricalEta3D.h:329
 CylindricalEta3D.h:330
 CylindricalEta3D.h:331
 CylindricalEta3D.h:332
 CylindricalEta3D.h:333
 CylindricalEta3D.h:334
 CylindricalEta3D.h:335
 CylindricalEta3D.h:336
 CylindricalEta3D.h:337
 CylindricalEta3D.h:338
 CylindricalEta3D.h:339
 CylindricalEta3D.h:340
 CylindricalEta3D.h:341
 CylindricalEta3D.h:342
 CylindricalEta3D.h:343
 CylindricalEta3D.h:344
 CylindricalEta3D.h:345
 CylindricalEta3D.h:346
 CylindricalEta3D.h:347
 CylindricalEta3D.h:348
 CylindricalEta3D.h:349
 CylindricalEta3D.h:350
 CylindricalEta3D.h:351
 CylindricalEta3D.h:352
 CylindricalEta3D.h:353