Go to the documentation of this file.00001
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
00014 }
00015
00016
00017
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
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
00252
00253 }
00254 }
00255 }
00256
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 }