CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/SimGeneral/GFlash/src/GflashTrajectory.cc

Go to the documentation of this file.
00001 // Most methods of this class are excerpted from CDF Helix and Trajectory class
00002 
00003 #include "SimGeneral/GFlash/interface/GflashTrajectory.h"
00004 
00005 GflashTrajectory::GflashTrajectory()
00006   :
00007    _cotTheta(0.0),_curvature(0.0),_z0(0.0),_d0(0.0),_phi0(0.0),
00008    _isStale(1),
00009    _sinPhi0(2),_cosPhi0(2),_sinTheta(2),_cosTheta(2),
00010    _s(-999.999),
00011    _aa(2),_ss(2),_cc(2)
00012 {
00013   //detault constructor
00014 }
00015 
00016 //GflashTrajectory::GflashTrajectory(const HepGeom::Vector3D<double>  & MomentumGev, const HepGeom::Point3D<double>   & PositionCm,
00017 //           double q, double BFieldTesla) 
00018 void GflashTrajectory::initializeTrajectory(const HepGeom::Vector3D<double>  & MomentumGev, const HepGeom::Point3D<double>   & PositionCm,
00019              double q, double BFieldTesla) 
00020  {
00021   double CotTheta = 0.0 ;
00022   double W = 0;
00023   double Z0 = 0;
00024   double D0 = 0;
00025   double Phi0 =0;
00026 
00027   if (BFieldTesla != 0.0 && q != 0.0) {
00028     double CurvatureConstant=0.0029979;
00029     double Helicity       = -1.0 * fabs(BFieldTesla) * fabs(q) / (BFieldTesla*q);
00030     double Radius         = fabs(MomentumGev.perp()/(CurvatureConstant*BFieldTesla*q));
00031     
00032     if(Radius==0.0) W = HUGE_VAL;   else     W        = Helicity/Radius;
00033     double phi1     = MomentumGev.phi();
00034     double x        = PositionCm.x(),        y        = PositionCm.y(),    z = PositionCm.z(); 
00035     double sinPhi1  = sin(phi1),             cosPhi1  = cos(phi1);
00036     double gamma    = atan((x*cosPhi1 + y*sinPhi1)/(x*sinPhi1-y*cosPhi1 -1/W));
00037     Phi0            = phi1+gamma;
00038     if(Phi0 >  M_PI) Phi0 = Phi0 - 2.0*M_PI; 
00039     if(Phi0 < -M_PI) Phi0 = Phi0 + 2.0*M_PI; 
00040     D0              = ((1/W + y*cosPhi1 - x*sinPhi1) /cos(gamma) - 1/W);
00041     CotTheta        = MomentumGev.z()/MomentumGev.perp();
00042     Z0              = z + gamma*CotTheta/W;
00043   }
00044   else {
00045     CLHEP::Hep3Vector direction          = MomentumGev.unit(); 
00046     CLHEP::Hep3Vector projectedDirection = CLHEP::Hep3Vector(direction.x(),direction.y(),0.0).unit();
00047     double s                      = projectedDirection.dot(PositionCm);
00048     double sprime                 = s/sin(direction.theta());
00049     Z0                            = (PositionCm - sprime*direction).z();
00050     Phi0                          = MomentumGev.phi();
00051     CotTheta                      = MomentumGev.z()/MomentumGev.perp();
00052     W                             = 0.0;
00053     D0                           = (PositionCm.y()*cos(Phi0) - PositionCm.x()*sin(Phi0));
00054   } 
00055   
00056    _cotTheta=CotTheta;
00057    _curvature=W/2;
00058    _z0=Z0;
00059    _d0=D0;
00060    _phi0=Phi0;
00061 
00062    _isStale=1;
00063    _s=-999.999;
00064    _aa =-999.999; 
00065    _ss =-999.999; 
00066    _cc =-999.999; 
00067    _sinPhi0 = 1.0;
00068    _cosPhi0 = 1.0;
00069    _sinTheta = 1.0;
00070    _cosTheta = 1.0;
00071 }
00072 
00073 GflashTrajectory::~GflashTrajectory()
00074 {
00075 }
00076 
00077 void GflashTrajectory::setCotTheta(double cotTheta) {
00078   _cotTheta=cotTheta;
00079   _isStale=true;
00080 }
00081 
00082 void GflashTrajectory::setCurvature(double curvature){
00083   _curvature=curvature;
00084   _isStale=true;
00085 }
00086 
00087 void GflashTrajectory::setZ0(double z0) {
00088   _z0 = z0;
00089   _isStale=true;
00090 }
00091 
00092 void GflashTrajectory::setD0(double d0){
00093   _d0=d0;
00094   _isStale=true;
00095 }
00096 
00097 void GflashTrajectory::setPhi0(double phi0){
00098   _phi0=phi0;
00099   _isStale=true;
00100 }
00101 
00102 double GflashTrajectory::getSinPhi0() const{
00103   _refreshCache();
00104   return _sinPhi0;
00105 }
00106 double GflashTrajectory::getCosPhi0() const{
00107   _refreshCache();
00108   return _cosPhi0;
00109 }
00110 double GflashTrajectory::getSinTheta() const{
00111   _refreshCache();
00112   return _sinTheta;
00113 }
00114 double GflashTrajectory::getCosTheta() const{
00115   _refreshCache();
00116   return _cosTheta;
00117 }
00118 
00119 HepGeom::Point3D<double>  GflashTrajectory::getPosition(double s) const
00120 {
00121   _cacheSinesAndCosines(s);
00122   if (s==0.0 || _curvature==0.0) {
00123       return HepGeom::Point3D<double> (-_d0*_sinPhi0+s*_cosPhi0*_sinTheta,
00124                         _d0*_cosPhi0+s*_sinPhi0*_sinTheta,
00125                         _z0+s*_cosTheta);
00126   } else {
00127       return HepGeom::Point3D<double> ((_cosPhi0*_ss-_sinPhi0*(2.0*_curvature*_d0+1.0-_cc))
00128                         /(2.0*_curvature),
00129                         (_sinPhi0*_ss+_cosPhi0*(2.0*_curvature*_d0+1.0-_cc))
00130                         /(2.0*_curvature),   
00131                         _s*_cosTheta + _z0);
00132   }
00133 }
00134 
00135 HepGeom::Vector3D<double>  GflashTrajectory::getDirection(double s) const
00136 {
00137   _cacheSinesAndCosines(s);
00138   if (s==0.0) {
00139       return HepGeom::Vector3D<double> (_cosPhi0*_sinTheta,_sinPhi0*_sinTheta,_cosTheta);
00140   }
00141   double   xtan     = _sinTheta*(_cosPhi0*_cc -_sinPhi0*_ss); 
00142   double   ytan     = _sinTheta*(_cosPhi0*_ss +_sinPhi0*_cc); 
00143   double ztan       = _cosTheta;
00144   return HepGeom::Vector3D<double> (xtan,ytan,ztan);
00145 }
00146 
00147 
00148 void GflashTrajectory::getGflashTrajectoryPoint(GflashTrajectoryPoint& point, double s) const {
00149   
00150   _cacheSinesAndCosines(s);
00151 
00152   double cP0sT = _cosPhi0*_sinTheta, sP0sT = _sinPhi0*_sinTheta;
00153   if ( s && _curvature) {
00154     point.getPosition().set((_cosPhi0*_ss-
00155                              _sinPhi0*(2.0*_curvature*_d0+1.0-_cc))
00156                             /(2.0*_curvature),
00157                             (_sinPhi0*_ss+
00158                              _cosPhi0*(2.0*_curvature*_d0+1.0-_cc))
00159                             /(2.0*_curvature),
00160                             s*_cosTheta + _z0);
00161     
00162     point.getMomentum().set(cP0sT*_cc-sP0sT*_ss,
00163                             cP0sT*_ss+sP0sT*_cc,
00164                             _cosTheta);
00165     point.setPathLength(s);
00166   }
00167   else {
00168     point.getPosition().set(-_d0*_sinPhi0+s*cP0sT,
00169                             _d0*_cosPhi0+s*sP0sT,
00170                             _z0+s*_cosTheta);
00171     
00172     point.getMomentum().set(cP0sT,sP0sT,_cosTheta);
00173     
00174     point.setPathLength(s);
00175   }
00176   
00177 }
00178 
00179 double GflashTrajectory::getPathLengthAtRhoEquals(double rho) const
00180 {
00181   return (getSinTheta()?(getL2DAtR(rho)/getSinTheta()):0.0);
00182 }
00183 
00184 double GflashTrajectory::getPathLengthAtZ(double z) const {
00185   return (getCosTheta()?(z-getZ0())/getCosTheta():0.0);
00186 }
00187 
00188 double GflashTrajectory::getZAtR(double rho) const {
00189   return _z0 + getCotTheta()*getL2DAtR(rho);
00190 }
00191 
00192 double GflashTrajectory::getL2DAtR(double rho) const {
00193 
00194   double L2D;
00195 
00196   double c = getCurvature();
00197   double d = getD0();
00198 
00199   if (c!=0.0) {
00200     double rad = (rho*rho-d*d)/(1.0+2.0*c*d);
00201     double rprime;
00202     if (rad<0.0) {
00203       rprime = 0.0;
00204     }
00205     else {
00206       rprime = sqrt( rad );
00207     }
00208     if (c*rprime > 1.0 || c*rprime < -1.0) {
00209       L2D = c*rprime > 0. ? M_PI/c : -M_PI/c;
00210     }
00211     else
00212       L2D = asin(c*rprime)/c;
00213   } else {
00214     double rad = rho*rho-d*d;
00215     double rprime;
00216     if (rad<0.0) rprime = 0.0;
00217     else rprime = sqrt( rad );
00218     
00219     L2D = rprime;
00220   }
00221   return L2D;
00222 }
00223 
00224 // Update _sinTheta,_cosTheta,_sinPhi0, and _cosPhi0
00225 void GflashTrajectory::_refreshCache() const {
00226   if (_isStale) {
00227     _isStale=false;
00228     double theta;
00229     if ( _cotTheta==0.0 ) {
00230        theta = M_PI/2.0;
00231     }
00232     else {
00233        theta=atan(1.0/_cotTheta);
00234        if (theta<0.0) theta+=M_PI;
00235     }
00236     if (theta==0.0) {
00237       _sinTheta=0.0;
00238       _cosTheta=1.0;
00239     }
00240     else {
00241       _cosTheta=cos(theta);
00242       _sinTheta=sqrt(1-_cosTheta*_cosTheta);
00243     }
00244     if (_phi0==0.0) {
00245       _sinPhi0=0.0;
00246       _cosPhi0=1.0;
00247     }
00248     else {
00249       _cosPhi0 = cos(_phi0);
00250       _sinPhi0 = sin(_phi0);
00251       //      _sinPhi0 = sqrt(1.0-_cosPhi0*_cosPhi0);
00252       //      if (_phi0>M_PI) _sinPhi0 = -_sinPhi0;
00253     }
00254   }
00255 }
00256 // Update _s, _aa, _ss, and _cc if the arclength has changed.
00257 void GflashTrajectory::_cacheSinesAndCosines(double s) const {
00258   _refreshCache();
00259   if (_s!=s){
00260     _s=s;
00261     _aa=2.0*_s*_curvature*_sinTheta;
00262     if (_aa==0.0) {
00263       _ss=0.0;
00264       _cc=1.0;
00265     }
00266     else {
00267       _ss=sin(_aa);
00268       _cc=cos(_aa);
00269     }
00270   }
00271 }