Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members

StableChargedParticle.C

Go to the documentation of this file.
00001 
00015 #include"StableChargedParticle.h"
00016 #include"cernlib.h"
00017 #include <cmath>
00018 #include <cassert>
00019 
00020 using std::sqrt;
00021 using std::sin;
00022 using std::cos;
00023 
00024 // constructor
00025 StableChargedParticle::StableChargedParticle(double kappa, double phi0, double theta, 
00026                                              double dca, double z0,
00027                                              double bfield_, double mass_)
00028   : bfield (bfield_), mass (mass_)
00029                                              {
00030   setParam (0, kappa, true);
00031   setParam (1, phi0, true);
00032   setParam (2, theta, true);
00033   setParam (3, dca, true);
00034   setParam (4, z0, true);
00035   setParam (5, 0, false);   // start tracklength
00036   setMass (m);
00037   for (int ilocal = 0; ilocal < NPAR; ++ilocal) globalParNum[ilocal] = -1;
00038   invalidateCache();
00039 }
00040 
00041 // destructor
00042 StableChargedParticle::~StableChargedParticle() {}
00043 
00044 // these depend on actual parametrisation!
00045 
00046 
00047     
00048 void   StableChargedParticle::addToDerivatives (double der[],
00049                                        int idim,
00050                                        double pxfact, 
00051                                        double pyfact, 
00052                                        double pzfact, 
00053                                        double efact) const {
00054   assert (0);                                     
00055   int i_E     = globalParNum[0];
00056   int i_theta = globalParNum[1];
00057   int i_phi   = globalParNum[2];
00058   assert (i_E     >= 0 && i_E     < idim);
00059   assert (i_theta >= 0 && i_theta < idim);
00060   assert (i_phi   >= 0 && i_phi   < idim);
00061   
00062   if (!cachevalid) updateCache();
00063   // for numerical accuracy, add up derivatives first,
00064   // then add them to global vector
00065   double der_E = 0;
00066   double der_theta = 0;
00067   double der_phi = 0;
00068   
00069   if (pxfact != 0) {
00070     der_E     += pxfact*dpxdE;
00071     der_theta += pxfact*dpydtheta;
00072     der_phi   -= pxfact*py;
00073   }
00074   if (pyfact != 0) {
00075     der_E     += pyfact*dpydE;
00076     der_theta += pyfact*dpydtheta;
00077     der_phi   += pyfact*px;
00078   }
00079   if (pzfact != 0) {
00080     der_E     += pzfact*dpdE*ctheta;
00081     der_theta -= pzfact*pt;
00082   }
00083   der_E     += efact;
00084   
00085   der[i_E]     += der_E;
00086   der[i_theta] += der_theta;
00087   der[i_phi]   += der_phi;
00088 }
00089     
00090 void   StableChargedParticle::addTo2ndDerivatives (double der2[],
00091                                           int idim,
00092                                           double pxfact, 
00093                                           double pyfact, 
00094                                           double pzfact, 
00095                                           double efact) const {
00096   int i_E  = globalParNum[0];
00097   int i_th = globalParNum[1];
00098   int i_ph= globalParNum[2];
00099   assert (i_E  >= 0 && i_E  < idim);
00100   assert (i_th >= 0 && i_th < idim);
00101   assert (i_ph >= 0 && i_ph < idim);
00102   
00103   if (!cachevalid) updateCache();
00104   // for numerical accuracy, add up derivatives first,
00105   // then add them to global vector
00106   double der_EE   = 0;
00107   double der_Eth  = 0;
00108   double der_Eph  = 0;
00109   double der_thth = 0;
00110   double der_thph = 0;
00111   double der_phph = 0;
00112   
00113   double d2pdE2 = (mass != 0) ? -mass*mass/(p*p*p) : 0;
00114   double d2ptdE2 = d2pdE2*stheta;
00115   
00116   if (pxfact != 0) {
00117     der_EE   += pxfact*d2ptdE2*cphi;
00118     der_Eth  += pxfact*dpzdE*cphi;
00119     der_Eph  -= pxfact*dpydE;
00120     der_thth -= pxfact*px;
00121     der_thph -= pxfact*dpydtheta;
00122     der_phph -= pxfact*px;
00123   }
00124   if (pyfact != 0) {
00125     der_EE   += pyfact*d2ptdE2*sphi;
00126     der_Eth  += pyfact*dpzdE*sphi;
00127     der_Eph  += pyfact*dpxdE;
00128     der_thth -= pyfact*py;
00129     der_thph += pyfact*dpxdtheta;
00130     der_phph -= pyfact*py;
00131   }
00132   if (pzfact != 0) {
00133     der_EE   += pzfact*d2pdE2*ctheta;
00134     der_Eth  -= pzfact*dptdE;
00135     der_thth -= pzfact*pz;
00136   }
00137   
00138   der2[idim*i_E+i_E]   += der_EE;
00139   der2[idim*i_E+i_th]  += der_Eth;
00140   der2[idim*i_E+i_ph]  += der_Eph;
00141   der2[idim*i_th+i_E]  += der_Eth;
00142   der2[idim*i_th+i_th] += der_thth;
00143   der2[idim*i_th+i_ph] += der_thph;
00144   der2[idim*i_ph+i_E]  += der_Eph;
00145   der2[idim*i_ph+i_th] += der_thph;
00146   der2[idim*i_ph+i_ph] += der_phph;
00147 }
00148 
00149 
00150     
00151 double StableChargedParticle::getChi2() const {
00152   if (!cachevalid) updateCache();
00153   return chi2;
00154 }
00155       
00156 void StableChargedParticle::addToGlobalChi2DerMatrix (int idim, double *M) const {
00157   assert (0);
00158   // Only diagonal terms d^2 chi^2 / dx_i dx_i are nonzero
00159   for (int ilocal = 0; ilocal < getNPar(); ++ilocal) {
00160     int iglobal = getGlobalParNum (ilocal);
00161     assert (iglobal >= 0 && iglobal < idim);
00162     M[(idim+1)*iglobal] += 2./std::pow (err[ilocal], 2);
00163   }
00164 }
00165   
00166       
00167 void StableChargedParticle::addToGlobalDerMatrix (int idim, double c, double *M) const {
00168   assert (0);
00169   // add second derivatives to global matrix
00170   if (c == 0) return;
00171   
00172   
00173 }
00174   
00175 double StableChargedParticle::getDChi2DParam(int ilocal) const {
00176   assert (ilocal >= 0 && ilocal < NPAR);
00177   if (ilocal >= NMEAS) return 0;
00178   if (!cachevalid) updateCache();
00179   double result = 0;
00180   for (int i = 0; i<NMEAS; i++) result += 2*covinv[ilocal][i]*resid[i];
00181   return ;
00182 }
00183     
00184 double StableChargedParticle::getD2Chi2DParam2(int ilocal1, int ilocal2) const {
00185   assert (ilocal1 >= 0 && ilocal1 < NPAR);
00186   assert (ilocal2 >= 0 && ilocal2 < NPAR);
00187   if (ilocal1 >= NMEAS || ilocal2 >= NMEAS ) return 0;
00188   return 2*covinv[ilocal1][ilocal2];
00189 }
00190 
00191 void StableChargedParticle::setCovMatrix(double values[NMEAS*(NMEAS+1)/2]) {
00192   for (int i = 0; i < NMEAS; ++i) {
00193     for (int j = 0; j < NMEAS; ++j) {
00194       covmatrix[i][j] = 0.;
00195     }
00196   } 
00197   int k=0;   
00198   for (int i = 0; i < NMEAS; ++i) {
00199     covinv[i][i] = covmatrix[i][i] = std::pow(values[k++], 2);
00200   }
00201   for (int i = 0; i < 4; ++i) {
00202     for (int j = i+1; j < NMEAS; ++j) {
00203       covinv[i][j] = covinv[j][i] = covmatrix[i][j] = covmatrix[j][i] = values[k++];
00204     }
00205   }
00206   int ifail = dsinv (NMEAS, covinv, NMEAS);
00207   assert (ifail == 0); 
00208 }
00209 
00210 void StableChargedParticle::addToGlobCov(double *cov, int idim) const {
00211   assert(0);
00212   for (int ilocal = 0; ilocal < NPAR; ilocal++) {
00213     int iglobal = getGlobalParNum(ilocal);
00214     if (iglobal >= 0) cov[iglobal*(1+idim)] += err[ilocal]*err[ilocal];
00215 //     std::cout << "cov[" << iglobal*(1+idim) << "] = " << cov[iglobal*(1+idim)]
00216 //               << " for idim = " << idim << " and ilocal = " << ilocal << std::endl;
00217   }
00218 }
00219 
00220 void StableChargedParticle::invalidateCache() const {
00221   cachevalid = false;
00222 }
00223 
00224 void StableChargedParticle::updateCache() const {
00225   double& kappa = par[0];
00226   double& phi0  = par[1];
00227   double& theta = par[2];
00228   double& dca   = par[3];
00229   double& z0    = par[4];
00230   double& s1    = par[5];
00231   
00232   sphi0 = std::sin(phi0);
00233   cphi0 = std::cos(phi0);
00234   r = (kappa != 0) ? 1/kappa : 0;
00235   dcamir = dca - r;
00236   cottheta = 1/std::tan(theta);
00237   cos2theta = std::pow (std::cos(theta), 2);
00238   
00239   setVertex (v1, dv1, 5, s1);
00240   
00241   chi2 = 0;
00242   for (int i = 0; i < NMEAS; ++i) {
00243     resid[i] = par[i]-measured[i];
00244     chi2 += resid[i]*covinv[i][i]*resid[i];
00245     for (int j = 0; j < i; ++j) {
00246       chi2 += 2*(resid[i])*covinv[i][j]*(resid[j])
00247     }
00248   }
00249   cachevalid = true;
00250 }
00251 void StableChargedParticle::setVertex (FitThreeVector& v, FitThreeVector dv[NPAR], 
00252                                        int n, double s) const {
00253   double& kappa = par[0];
00254   double& dca   = par[3];
00255   double& z0    = par[4];
00256   
00257   if (std::abs (kappa*s) < 1.e-6) {
00258     double ssq = s*s;
00259     double kssq = 0.5*kappa*ssq;
00260     v.setValues (sphi0*( dca + kssq) - cphi0*s,
00261                  cphi0*(-dca + kssq) + sphi0*s,
00262                  z0 + s*cottheta);
00263     dv[0].setValues (-0.5*sphi0*ssq,
00264                       0.5*cphi0*ssq, 
00265                      0);          
00266   }
00267   else {
00268     double kappas = kappa*s;
00269     double phi0plkappas = phi0 + kappas;
00270     double si = std::sin(phi0plkappas);
00271     double co = std::cos(phi0plkappas);
00272     v.setValues ( dcamir*sphi0 + r*si,
00273                  -dcamir*cphi0 - r*co,
00274                  z0 + s*cottheta);
00275     dv[0].setValues (co*kappas + sphi0 -si,
00276                      si*kappas - cphi0 +co, 
00277                      0);          
00278   }
00279   dv[1].setValues (-v.getY(),
00280                    -v.getX(), 
00281                    0);          
00282   dv[2].setValues (0, 0, - s/cos2theta);          
00283   dv[3].setValues (sphi0, -cphi0, 0);          
00284   dv[4].setValues (0, 0, 1);  
00285   assert (n<NPAR);        
00286   dv[n].setValues (co, si, cottheta);          
00287 }

Generated on Fri Sep 14 17:38:21 2007 for Kinfit by doxygen 1.3.2