CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Validation/EcalClusters/interface/AnglesUtil.h

Go to the documentation of this file.
00001 #ifndef INC_ANGLESUTIL
00002 #define INC_ANGLESUTIL
00003 
00004 // File: AnglesUtil.hpp
00005 // 
00006 // Purpose:  Provide useful functions for calculating angles and eta
00007 //
00008 // Created:   4-NOV-1998  Serban Protopopescu
00009 // History:   replaced old KinemUtil  
00010 // Modified:  23-July-2000 Add rapidity calculation
00011 //            14-Aug-2003 converted all functions to double precision
00013 // Dependencies (#includes)
00014 
00015 #include <cmath>
00016 #include <cstdlib>
00017 
00018 
00019 namespace kinem{
00020   const double PI=2.0*acos(0.);
00021   const double TWOPI=2.0*PI;
00022   const float ETA_LIMIT=15.0;
00023   const float EPSILON=1.E-10;
00024 
00025   //  calculate phi from x, y
00026   inline double phi(double x, double y);
00027   //  calculate phi for a line defined by xy1 and xy2 (xy2-xy1)
00028   inline double phi(double xy1[2], double xy2[2]);
00029   inline double phi(float xy1[2], float xy2[2]);
00030 
00031   //  calculate theta from x, y, z
00032   inline double theta(double x, double y, double z);
00033   //  calculate theta for a line defined by xyz1 and xyz2 (xyz2-xyz1)
00034   inline double theta(double xyz1[3], double xyz2[3]);
00035   inline double theta(float xyz1[3], float xyz2[3]);
00036   //  calculate theta from eta
00037   inline double theta(double etap);
00038 
00039   //  calculate eta from x, y, z (return also theta)
00040   inline double eta(double x, double y, double z);
00041   //  calculate eta for a line defined by xyz1 and xyz2 (xyz2-xyz1)
00042   inline double eta(double xyz1[3], double xyz2[3]);
00043   inline double eta(float xyz1[3], float xyz2[3]);
00044   //  calculate eta from theta
00045   inline double eta(double th);
00046 
00047   // calculate rapidity from E, pz
00048   inline double y(double E, double pz);
00049 
00050   //  calculate phi1-phi2 keeping value between 0 and pi
00051   inline double delta_phi(double ph11, double phi2);
00052   // calculate phi1-phi2 keeping value between -pi and pi
00053   inline double signed_delta_phi(double ph11, double phi2);
00054   // calculate eta1 - eta2
00055   inline double delta_eta(double eta1, double eta2);
00056 
00057   //  calculate deltaR
00058   inline double delta_R(double eta1, double phi1, double eta2, double phi2);
00059 
00060   //  calculate unit vectors given two points
00061   inline void uvectors(double u[3], double xyz1[3], double xyz2[3]);
00062   inline void uvectors(float u[3], float xyz1[3], float xyz2[3]);
00063 
00064   inline double tanl_from_theta(double theta);
00065   inline double theta_from_tanl(double tanl); 
00066 }
00067 
00068 inline
00069 double kinem::phi(double x, double y)
00070 {
00071   double PHI=atan2(y, x);
00072   return (PHI>=0)? PHI : kinem::TWOPI+PHI;
00073 }
00074 
00075 inline 
00076 double kinem::phi(float xy1[2], float xy2[2]){
00077     double dxy1[2]={xy1[0],xy1[1]};
00078     double dxy2[2]={xy2[0],xy2[1]};
00079     return phi(dxy1,dxy2);
00080   }
00081 
00082 inline
00083 double kinem::phi(double xy1[2], double xy2[2])
00084 {
00085   double x=xy2[0]-xy1[0];
00086   double y=xy2[1]-xy1[1];
00087   return phi(x, y);
00088 }
00089 
00090 inline
00091 double kinem::delta_phi(double phi1, double phi2)
00092 {
00093   double PHI=fabs(phi1-phi2);
00094   return (PHI<=PI)? PHI : kinem::TWOPI-PHI;
00095 }
00096 
00097 inline
00098 double kinem::delta_eta(double eta1, double eta2)
00099 {
00100   return eta1 - eta2;
00101 }
00102 
00103 inline
00104 double kinem::signed_delta_phi(double phi1, double phi2)
00105 {
00106   double phia=phi1;
00107   if(phi1>PI) phia=phi1-kinem::TWOPI;
00108   double phib=phi2;
00109   if(phi2>PI) phib=phi2-kinem::TWOPI;
00110   double dphi=phia-phib;
00111   if(dphi>PI) dphi-=kinem::TWOPI;
00112   if(dphi<-PI) dphi+=kinem::TWOPI;
00113   return dphi;
00114 }
00115 
00116 inline double kinem::delta_R(double eta1, double phi1, double eta2, double phi2)
00117 {
00118    double deta = eta1-eta2;
00119    double dphi = kinem::delta_phi(phi1,phi2);
00120    return sqrt(deta*deta + dphi*dphi);
00121 }
00122 
00123 inline
00124 double kinem::theta(double xyz1[3], double xyz2[3])
00125 {
00126   double x=xyz2[0]-xyz1[0];
00127   double y=xyz2[1]-xyz1[1];
00128   double z=xyz2[2]-xyz1[2];
00129   return theta(x, y, z);
00130 }
00131 
00132 inline 
00133 double kinem::theta(float xyz1[3], float xyz2[3]){
00134     double dxyz1[3]={xyz1[0],xyz1[1],xyz1[2]};
00135     double dxyz2[3]={xyz2[0],xyz2[1],xyz2[2]};
00136     return theta(dxyz1,dxyz2);
00137 }
00138 
00139 inline 
00140 double kinem::theta(double x, double y, double z)
00141 {
00142   return atan2(sqrt(x*x + y*y), z);
00143 }
00144 
00145 inline 
00146 double kinem::theta(double etap)
00147 {
00148   return 2.0*atan(exp(-etap));
00149 }
00150 
00151 inline
00152 double kinem::eta(double xyz1[3], double xyz2[3])
00153 {
00154   double x=xyz2[0]-xyz1[0];
00155   double y=xyz2[1]-xyz1[1];
00156   double z=xyz2[2]-xyz1[2];
00157   return eta(x, y, z);
00158 }
00159 
00160 inline
00161 double kinem::eta(float xyz1[3], float xyz2[3]){
00162     double dxyz1[3]={xyz1[0],xyz1[1],xyz1[2]};
00163     double dxyz2[3]={xyz2[0],xyz2[1],xyz2[2]};
00164     return eta(dxyz1,dxyz2);
00165 }
00166 
00167 inline
00168 double kinem::eta(double x, double y, double z)
00169 {
00170   return 0.5*log((sqrt(x*x + y*y + z*z) + z + EPSILON) / 
00171                  (sqrt(x*x + y*y + z*z) - z + EPSILON));
00172 }
00173 
00174 inline
00175 double kinem::eta(double th)
00176 {
00177   if(th == 0) return ETA_LIMIT;
00178   if(th >= PI-0.0001) return -ETA_LIMIT;
00179   return -log(tan(th/2.0));
00180 }
00181 
00182 inline 
00183 double kinem::y(double E, double pz)
00184 {
00185   return 0.5 * log ((E+pz+EPSILON)/(E-pz+EPSILON));
00186 }
00187 
00188 inline
00189 void kinem::uvectors(double u[3], double xyz1[3], double xyz2[3]){
00190   double xdiff=xyz2[0]-xyz1[0];
00191   double ydiff=xyz2[1]-xyz1[1];
00192   double zdiff=xyz2[2]-xyz1[2];
00193   double s=sqrt(xdiff*xdiff+ydiff*ydiff+zdiff*zdiff);
00194   if(s > 0) {
00195     u[0]=xdiff/s;
00196     u[1]=ydiff/s;
00197     u[2]=zdiff/s;
00198   }else{
00199     u[0]=0;
00200     u[1]=0;
00201     u[2]=0;
00202   }
00203 }
00204 
00205 inline 
00206 void kinem::uvectors(float u[3], float xyz1[3], float xyz2[3]){
00207     double du[3];
00208     double dxyz1[3]={xyz1[0],xyz1[1],xyz1[2]};
00209     double dxyz2[3]={xyz2[0],xyz2[1],xyz2[2]};
00210     uvectors(du,dxyz1,dxyz2);
00211     u[0]=du[0];
00212     u[1]=du[1];
00213     u[2]=du[2];
00214 }
00215 
00216 inline
00217 double kinem::tanl_from_theta(double theta){
00218   return tan(PI/2.0 - theta);
00219 }
00220 
00221 inline
00222 double kinem::theta_from_tanl(double tanl){
00223   return PI/2.0 - atan(tanl);
00224 }
00225 
00226 #endif // INC_ANGLESUTIL