CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:47:05 2009 for CMSSW by  doxygen 1.5.4