// @(#)root/mathcore:$Id$
// Authors: W. Brown, M. Fischler, L. Moneta    2005

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

// Header file for class Cylindrica3D
//
// Created by: Lorenzo Moneta  at Tue Dec 06 2005
//
//
#ifndef ROOT_Math_GenVector_Cylindrical3D
#define ROOT_Math_GenVector_Cylindrical3D  1

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

#ifndef ROOT_Math_GenVector_eta
#include "Math/GenVector/eta.h"
#endif

#include <limits>


namespace ROOT {

namespace Math {

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

      @ingroup GenVector
  */

template <class T>
class Cylindrical3D {

public :

   typedef T Scalar;

   /**
      Default constructor with rho=z=phi=0
   */
   Cylindrical3D() : fRho(0), fZ(0), fPhi(0) {  }

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

   /**
      Construct from any Vector or coordinate system implementing
      Rho(), Z() and Phi()
   */
   template <class CoordSystem >
   explicit Cylindrical3D( const CoordSystem & v ) :
      fRho( v.Rho() ),  fZ( v.Z() ),  fPhi( v.Phi() ) { Restrict(); }

   // 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
    */
   Cylindrical3D(const Cylindrical3D & v) :
      fRho(v.Rho() ),  fZ(v.Z() ),  fPhi(v.Phi() )  {   }

   /**
      assignment operator
    */
   Cylindrical3D & operator= (const Cylindrical3D & v) {
      fRho = v.Rho();
      fZ   = v.Z();
      fPhi = v.Phi();
      return *this;
   }

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

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

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

   /**
      get internal data into 3 Scalar numbers ( rho, z , phi)
   */
   void GetCoordinates(Scalar& rho, Scalar& zz, Scalar& phi) const
   {rho=fRho; zz=fZ; 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

   Scalar Rho()   const { return fRho; }
   Scalar Z()     const { return fZ;   }
   Scalar Phi()   const { return fPhi; }

   Scalar X()     const { return fRho*std::cos(fPhi); }
   Scalar Y()     const { return fRho*std::sin(fPhi); }

   Scalar Mag2()  const { return fRho*fRho + fZ*fZ;   }
   Scalar R()     const { return std::sqrt( Mag2());  }
   Scalar Perp2() const { return fRho*fRho;           }
   Scalar Theta() const { return (fRho==0 && fZ==0 ) ? 0 : atan2(fRho,fZ); }

   // pseudorapidity - use same implementation as in Cartesian3D
   Scalar Eta() const {
      return Impl::Eta_FromRhoZ( fRho, fZ);
   }

   // setters (only for data members)


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

   /**
       set the z coordinate value keeping rho and phi constant
   */
   void SetZ(T zz) {
      fZ = zz;
   }

   /**
       set the phi coordinate value keeping rho and z 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 coords only rho and z change
   */
   void Scale (T a) {
      if (a < 0) {
         Negate();
         a = -a;
      }
      fRho *= a;
      fZ *= a;
   }

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

   // assignment operators
   /**
      generic assignment operator from any coordinate system implementing Rho(), Z() and Phi()
   */
   template <class CoordSystem >
   Cylindrical3D & operator= ( const CoordSystem & c ) {
      fRho = c.Rho();
      fZ   = c.Z();
      fPhi = c.Phi();
      return *this;
   }

   /**
      Exact component-by-component equality
   */
   bool operator==(const Cylindrical3D & rhs) const {
      return fRho == rhs.fRho && fZ == rhs.fZ && fPhi == rhs.fPhi;
   }
   bool operator!= (const Cylindrical3D & 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 SetEta(Scalar eta);

   void SetR(Scalar r);

   void SetTheta(Scalar theta);

#endif


private:

   T fRho;
   T fZ;
   T fPhi;

};

  } // end namespace Math

} // end namespace ROOT

// move implementations here to avoid circle dependencies

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

#if defined(__MAKECINT__) || defined(G__DICTIONARY)
#ifndef ROOT_Math_GenVector_GenVector_exception
#include "Math/GenVector/GenVector_exception.h"
#endif
#ifndef ROOT_Math_GenVector_CylindricalEta3D
#include "Math/GenVector/CylindricalEta3D.h"
#endif
#ifndef ROOT_Math_GenVector_Polar3D
#include "Math/GenVector/Polar3D.h"
#endif
#endif

namespace ROOT {

  namespace Math {

template <class T>
void Cylindrical3D<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 Cylindrical3D<T>::SetX(Scalar xx) {
   GenVector_exception e("Cylindrical3D::SetX() is not supposed to be called");
   throw e;
   Cartesian3D<Scalar> v(*this); v.SetX(xx); *this = Cylindrical3D<Scalar>(v);
}
template <class T>
void Cylindrical3D<T>::SetY(Scalar yy) {
   GenVector_exception e("Cylindrical3D::SetY() is not supposed to be called");
   throw e;
   Cartesian3D<Scalar> v(*this); v.SetY(yy); *this = Cylindrical3D<Scalar>(v);
}
template <class T>
void Cylindrical3D<T>::SetR(Scalar r) {
   GenVector_exception e("Cylindrical3D::SetR() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetR(r);
   *this = Cylindrical3D<Scalar>(v);
}
template <class T>
void Cylindrical3D<T>::SetTheta(Scalar theta) {
   GenVector_exception e("Cylindrical3D::SetTheta() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetTheta(theta);
   *this = Cylindrical3D<Scalar>(v);
}
template <class T>
void Cylindrical3D<T>::SetEta(Scalar eta) {
   GenVector_exception e("Cylindrical3D::SetEta() is not supposed to be called");
   throw e;
   CylindricalEta3D<Scalar> v(*this); v.SetEta(eta);
   *this = Cylindrical3D<Scalar>(v);
}

#endif

  } // end namespace Math

} // end namespace ROOT


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