CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/TrackingTools/AnalyticalJacobians/src/AnalyticalCurvilinearJacobian.cc

Go to the documentation of this file.
00001 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00002 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00003 
00004 AnalyticalCurvilinearJacobian::AnalyticalCurvilinearJacobian 
00005 (const GlobalTrajectoryParameters& globalParameters,
00006  const GlobalPoint& x, 
00007  const GlobalVector& p, 
00008  const double& s) :  theJacobian(AlgebraicMatrixID())
00009 {
00010   //
00011   // helix: calculate full jacobian
00012   //
00013   if ( s*s*fabs(globalParameters.transverseCurvature())>1.e-5 ) { 
00014     GlobalPoint xStart = globalParameters.position();
00015     GlobalVector h  = globalParameters.magneticFieldInInverseGeV(xStart);
00016     computeFullJacobian(globalParameters,x,p,h,s);
00017   }
00018   //
00019   // straight line approximation, error in RPhi about 0.1um
00020   //
00021   else
00022     computeStraightLineJacobian(globalParameters,x,p,s);
00023    //dbg::dbg_trace(1,"ACJ1", globalParameters.vector(),x,p,s,theJacobian);
00024 }
00025 
00026 
00027 AnalyticalCurvilinearJacobian::AnalyticalCurvilinearJacobian
00028 (const GlobalTrajectoryParameters& globalParameters,
00029  const GlobalPoint& x, 
00030  const GlobalVector& p, 
00031  const GlobalVector& h, // h is the magnetic Field in Inverse GeV
00032  const double& s) :  theJacobian(AlgebraicMatrixID())
00033 {
00034   //
00035   // helix: calculate full jacobian
00036   //
00037   if ( s*s*fabs(globalParameters.transverseCurvature())>1.e-5 )
00038     computeFullJacobian(globalParameters,x,p,h,s);
00039   //
00040   // straight line approximation, error in RPhi about 0.1um
00041   //
00042   else
00043     computeStraightLineJacobian(globalParameters,x,p,s);
00044   
00045   //dbg::dbg_trace(1,"ACJ2", globalParameters.vector(),x,p,s,theJacobian);
00046 }
00047 
00048 
00049 #if defined(USE_SSEVECT) && !defined(TRPRFN_SCALAR)
00050 #include "AnalyticalCurvilinearJacobianSSE.icc"
00051 #elif defined(USE_EXTVECT) && !defined(TRPRFN_SCALAR)
00052 #include "AnalyticalCurvilinearJacobianEXT.icc"
00053 
00054 #else
00055 
00056 void
00057 AnalyticalCurvilinearJacobian::computeFullJacobian
00058 (const GlobalTrajectoryParameters& globalParameters,
00059  const GlobalPoint& x, 
00060  const GlobalVector& p, 
00061  const GlobalVector& h, 
00062  const double& s)
00063 {    
00064   //GlobalVector p1 = fts.momentum().unit();
00065   GlobalVector p1 = globalParameters.momentum().unit();
00066   GlobalVector p2 = p.unit();
00067   //GlobalPoint xStart = fts.position();
00068   GlobalPoint xStart = globalParameters.position();
00069   GlobalVector dx = xStart - x;
00070   //GlobalVector h  = MagneticField::inInverseGeV(xStart);
00071   // Martijn: field is now given as parameter.. GlobalVector h  = globalParameters.magneticFieldInInverseGeV(xStart);
00072 
00073   //double qbp = fts.signedInverseMomentum();
00074   double qbp = globalParameters.signedInverseMomentum();
00075   double absS = s;
00076   
00077   // calculate transport matrix
00078   // Origin: TRPRFN
00079   double t11 = p1.x(); double t12 = p1.y(); double t13 = p1.z();
00080   double t21 = p2.x(); double t22 = p2.y(); double t23 = p2.z();
00081   double cosl0 = p1.perp(); double cosl1 = 1./p2.perp();
00082   //AlgebraicMatrix a(5,5,1);
00083   // define average magnetic field and gradient 
00084   // at initial point - inlike TRPRFN
00085   GlobalVector hn = h.unit();
00086   double qp = -h.mag();
00087 //   double q = -h.mag()*qbp;
00088   double q = qp*qbp;
00089   double theta = q*absS; double sint = sin(theta); double cost = cos(theta);
00090   double hn1 = hn.x(); double hn2 = hn.y(); double hn3 = hn.z();
00091   double dx1 = dx.x(); double dx2 = dx.y(); double dx3 = dx.z();
00092   double gamma = hn1*t21 + hn2*t22 + hn3*t23;
00093   double an1 = hn2*t23 - hn3*t22;
00094   double an2 = hn3*t21 - hn1*t23;
00095   double an3 = hn1*t22 - hn2*t21;
00096   double au = 1./sqrt(t11*t11 + t12*t12);
00097   double u11 = -au*t12; double u12 = au*t11;
00098   double v11 = -t13*u12; double v12 = t13*u11; double v13 = t11*u12 - t12*u11;
00099   au = 1./sqrt(t21*t21 + t22*t22);
00100   double u21 = -au*t22; double u22 = au*t21;
00101   double v21 = -t23*u22; double v22 = t23*u21; double v23 = t21*u22 - t22*u21;
00102   // now prepare the transport matrix
00103   // pp only needed in high-p case (WA)
00104 //   double pp = 1./qbp;
00106 // moved up (where -h.mag() is needed()
00107 //   double qp = q*pp;
00108   double anv = -(hn1*u21 + hn2*u22          );
00109   double anu =  (hn1*v21 + hn2*v22 + hn3*v23);
00110   double omcost = 1. - cost; double tmsint = theta - sint;
00111   
00112   double hu1 =         - hn3*u12;
00113   double hu2 = hn3*u11;
00114   double hu3 = hn1*u12 - hn2*u11;
00115   
00116   double hv1 = hn2*v13 - hn3*v12;
00117   double hv2 = hn3*v11 - hn1*v13;
00118   double hv3 = hn1*v12 - hn2*v11;
00119   
00120   //   1/p - doesn't change since |p1| = |p2|
00121   
00122   //   lambda
00123   
00124   theJacobian(1,0) = -qp*anv*(t21*dx1 + t22*dx2 + t23*dx3);
00125   
00126   theJacobian(1,1) = cost*(v11*v21 + v12*v22 + v13*v23) +
00127                       sint*(hv1*v21 + hv2*v22 + hv3*v23) +
00128                     omcost*(hn1*v11 + hn2*v12 + hn3*v13) *
00129                            (hn1*v21 + hn2*v22 + hn3*v23) +
00130                 anv*(-sint*(v11*t21 + v12*t22 + v13*t23) +
00131                     omcost*(v11*an1 + v12*an2 + v13*an3) -
00132               tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
00133 
00134   theJacobian(1,2) = cost*(u11*v21 + u12*v22          ) +
00135                       sint*(hu1*v21 + hu2*v22 + hu3*v23) +
00136                     omcost*(hn1*u11 + hn2*u12          ) *
00137                            (hn1*v21 + hn2*v22 + hn3*v23) +
00138                 anv*(-sint*(u11*t21 + u12*t22          ) +
00139                     omcost*(u11*an1 + u12*an2          ) -
00140               tmsint*gamma*(hn1*u11 + hn2*u12          ) );
00141   theJacobian(1,2) *= cosl0;
00142 
00143   theJacobian(1,3) = -q*anv*(u11*t21 + u12*t22          );
00144 
00145   theJacobian(1,4) = -q*anv*(v11*t21 + v12*t22 + v13*t23);
00146 
00147   //   phi
00148 
00149   theJacobian(2,0) = -qp*anu*(t21*dx1 + t22*dx2 + t23*dx3)*cosl1;
00150 
00151   theJacobian(2,1) = cost*(v11*u21 + v12*u22          ) +
00152                       sint*(hv1*u21 + hv2*u22          ) +
00153                     omcost*(hn1*v11 + hn2*v12 + hn3*v13) *
00154                            (hn1*u21 + hn2*u22          ) +
00155                 anu*(-sint*(v11*t21 + v12*t22 + v13*t23) +
00156                     omcost*(v11*an1 + v12*an2 + v13*an3) -
00157               tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
00158   theJacobian(2,1) *= cosl1;
00159 
00160   theJacobian(2,2) = cost*(u11*u21 + u12*u22          ) +
00161                       sint*(hu1*u21 + hu2*u22          ) +
00162                     omcost*(hn1*u11 + hn2*u12          ) *
00163                            (hn1*u21 + hn2*u22          ) +
00164                 anu*(-sint*(u11*t21 + u12*t22          ) +
00165                     omcost*(u11*an1 + u12*an2          ) -
00166               tmsint*gamma*(hn1*u11 + hn2*u12          ) );
00167   theJacobian(2,2) *= cosl1*cosl0;
00168 
00169   theJacobian(2,3) = -q*anu*(u11*t21 + u12*t22          )*cosl1;
00170 
00171   theJacobian(2,4) = -q*anu*(v11*t21 + v12*t22 + v13*t23)*cosl1;
00172 
00173   //   yt
00174 
00175   //double cutCriterion = abs(s/fts.momentum().mag());
00176   double cutCriterion = fabs(s/globalParameters.momentum().mag());
00177   const double limit = 5.; // valid for propagations with effectively float precision
00178 
00179   if (cutCriterion > limit) {
00180     double pp = 1./qbp;
00181     theJacobian(3,0) = pp*(u21*dx1 + u22*dx2            );
00182     theJacobian(4,0) = pp*(v21*dx1 + v22*dx2 + v23*dx3);
00183   }
00184   else {
00185     double hp11 = hn2*t13 - hn3*t12;
00186     double hp12 = hn3*t11 - hn1*t13;
00187     double hp13 = hn1*t12 - hn2*t11;
00188     double temp1 = hp11*u21 + hp12*u22;
00189     double s2 = s*s;
00190     double secondOrder41 = 0.5 * qp * temp1 * s2;
00191     double ghnmp1 = gamma*hn1 - t11;
00192     double ghnmp2 = gamma*hn2 - t12;
00193     double ghnmp3 = gamma*hn3 - t13;
00194     double temp2 = ghnmp1*u21 + ghnmp2*u22;
00195     double s3 = s2 * s;
00196     double s4 = s3 * s;
00197     double h1 = h.mag();
00198     double h2 = h1 * h1;
00199     double h3 = h2 * h1;
00200     double qbp2 = qbp * qbp;
00201     //                           s*qp*s* (qp*s *qbp)
00202     double thirdOrder41 = 1./3 * h2 * s3 * qbp * temp2;
00203     //                           -qp * s * qbp  * above
00204     double fourthOrder41 = 1./8 * h3 * s4 * qbp2 * temp1;
00205     theJacobian(3,0) = secondOrder41 + (thirdOrder41 + fourthOrder41);
00206 
00207     double temp3 = hp11*v21 + hp12*v22 + hp13*v23;
00208     double secondOrder51 = 0.5 * qp * temp3 * s2;
00209     double temp4 = ghnmp1*v21 + ghnmp2*v22 + ghnmp3*v23;
00210     double thirdOrder51 = 1./3 * h2 * s3 * qbp * temp4;
00211     double fourthOrder51 = 1./8 * h3 * s4 * qbp2 * temp3;
00212     theJacobian(4,0) = secondOrder51 + (thirdOrder51 + fourthOrder51);
00213   }
00214 
00215   theJacobian(3,1) = (sint*(v11*u21 + v12*u22          ) +
00216                      omcost*(hv1*u21 + hv2*u22          ) +
00217                      tmsint*(hn1*u21 + hn2*u22          ) *
00218                             (hn1*v11 + hn2*v12 + hn3*v13))/q;
00219 
00220   theJacobian(3,2) = (sint*(u11*u21 + u12*u22          ) +
00221                      omcost*(hu1*u21 + hu2*u22          ) +
00222                      tmsint*(hn1*u21 + hn2*u22          ) *
00223                             (hn1*u11 + hn2*u12          ))*cosl0/q;
00224 
00225   theJacobian(3,3) = (u11*u21 + u12*u22          );
00226   
00227   theJacobian(3,4) = (v11*u21 + v12*u22          );
00228 
00229   //   zt
00230 
00231   theJacobian(4,1) = (sint*(v11*v21 + v12*v22 + v13*v23) +
00232                      omcost*(hv1*v21 + hv2*v22 + hv3*v23) +
00233                      tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
00234                             (hn1*v11 + hn2*v12 + hn3*v13))/q;
00235 
00236   theJacobian(4,2) = (sint*(u11*v21 + u12*v22          ) +
00237                      omcost*(hu1*v21 + hu2*v22 + hu3*v23) +
00238                      tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
00239                             (hn1*u11 + hn2*u12          ))*cosl0/q;
00240 
00241   theJacobian(4,3) = (u11*v21 + u12*v22          );
00242 
00243   theJacobian(4,4) = (v11*v21 + v12*v22 + v13*v23);
00244   // end of TRPRFN
00245 }
00246 
00247 #endif
00248 
00249 void AnalyticalCurvilinearJacobian::computeInfinitesimalJacobian 
00250 (const GlobalTrajectoryParameters& globalParameters,
00251  const GlobalPoint&, 
00252  const GlobalVector& p, 
00253  const GlobalVector& h, 
00254  const double& s) {
00255   /*
00256    * origin  TRPROP
00257    *
00258    C *** ERROR PROPAGATION ALONG A PARTICLE TRAJECTORY IN A MAGNETIC FIELD
00259    C     ROUTINE ASSUMES THAT IN THE INTERVAL (X1,X2) THE QUANTITIES 1/P
00260    C     AND (HX,HY,HZ) ARE RATHER CONSTANT. DELTA(PHI) MUST NOT BE TOO LARGE
00261    C
00262    C     Authors: A. Haas and W. Wittek
00263    C
00264    
00265   */
00266   
00267   
00268   double qbp = globalParameters.signedInverseMomentum();
00269   double absS = s;
00270   
00271   // average momentum
00272   GlobalVector tn = (globalParameters.momentum()+p).unit(); 
00273   double sinl = tn.z(); 
00274   double cosl = std::sqrt(1.-sinl*sinl); 
00275   double cosl1 = 1./cosl;
00276   double tgl=sinl*cosl1;
00277   double sinp = tn.y()*cosl1;
00278   double cosp = tn.x()*cosl1;
00279 
00280   // define average magnetic field and gradient 
00281   // at initial point - inlike TRPROP
00282   double b0= h.x()*cosp+h.y()*sinp;
00283   double b2=-h.x()*sinp+h.y()*cosp;
00284   double b3=-b0*sinl+h.z()*cosl;
00285 
00286   theJacobian(3,2)=absS*cosl;
00287   theJacobian(4,1)=absS;
00288 
00289 
00290   theJacobian(1,0) =  absS*b2;
00291   //if ( qbp<0) theJacobian(1,0) = -theJacobian(1,0);
00292   theJacobian(1,2) = -b0*(absS*qbp);
00293   theJacobian(1,3) =  b3*(b2*qbp*(absS*qbp));
00294   theJacobian(1,4) = -b2*(b2*qbp*(absS*qbp));
00295   
00296   theJacobian(2,0) = -absS*b3*cosl1;
00297   // if ( qbp<0) theJacobian(2,0) = -theJacobian(2,0);
00298   theJacobian(2,1) = b0*(absS*qbp)*cosl1*cosl1;
00299   theJacobian(2,2) = 1.+tgl*b2*(absS*qbp);
00300   theJacobian(2,3) = -b3*(b3*qbp*(absS*qbp)*cosl1);
00301   theJacobian(2,4) =  b2*(b3*qbp*(absS*qbp)*cosl1);
00302   
00303   theJacobian(3,4) = -b3*tgl*(absS*qbp);
00304   theJacobian(4,3) =  b3*tgl*(absS*qbp);
00305 
00306 
00307 }
00308 
00309 void
00310 AnalyticalCurvilinearJacobian::computeStraightLineJacobian
00311 (const GlobalTrajectoryParameters& globalParameters,
00312  const GlobalPoint& x, const GlobalVector& p, const double& s)
00313 {
00314   //
00315   // matrix: elements =1 on diagonal and =0 are already set
00316   // in initialisation
00317   //
00318   GlobalVector p1 = globalParameters.momentum().unit();
00319   double cosl0 = p1.perp();
00320   theJacobian(3,2) = cosl0 * s;
00321   theJacobian(4,1) = s;
00322 }