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

NeutralParticleTrack.C

Go to the documentation of this file.
00001 
00008 #include "jbltools/kinfit/NeutralParticleTrack.h"
00009 #include "jbltools/kinfit/TwoVector.h"
00010 #include "jbltools/kinfit/ThreeVector.h"
00011 #include "jbltools/kinfit/FourVector.h"
00012 #include "jbltools/kinfit/JBLHelix.h"
00013 
00014 #include <cassert>
00015 #include <cmath>
00016 using std::sin;
00017 using std::cos;
00018 using std::sqrt;
00019 using std::tan;
00020 using std::pow;
00021 using std::abs;
00022 using std::isfinite;
00023 #include <iostream>
00024 using std::cout;
00025 using std::endl;
00026 
00027 
00028 const double NeutralParticleTrack::parfact[NPARMAX] = 
00029   {1., 1., 1., 1., 1., 1., 1., 1.};
00030 
00031 NeutralParticleTrack::NeutralParticleTrack (const char *name_,
00032                                             double pt,
00033                                             double phi0,
00034                                             double theta,
00035                                             double dca,
00036                                             double z0,
00037                                             double mass,
00038                                             double sstart,
00039                                             double sstop
00040                                             )
00041 : TrackFitObject (name_) 
00042 {
00043   setParam (0, pt, false);
00044   setParam (1, phi0, false);
00045   setParam (2, theta, false);
00046   setParam (3, dca, false);
00047   setParam (4, z0, false);
00048   setParam (5, mass, false, true);
00049   setParam (6, sstart, false);
00050   setParam (7, sstop, false);
00051   // setParam (6, sstop, false);
00052   setMParam (0, pt);
00053   setMParam (1, phi0);
00054   setMParam (2, theta);
00055   setMParam (3, dca);
00056   setMParam (4, z0);
00057   TrackFitObject::initCov();
00058 }
00059 NeutralParticleTrack::NeutralParticleTrack (const char *name_,
00060                                             double pt,
00061                                             double phi0,
00062                                             double theta,
00063                                             double dca,
00064                                             double z0,
00065                                             double mass,
00066                                             double sstart
00067                                             )
00068 : TrackFitObject (name_) 
00069 {
00070   setParam (0, pt, false);
00071   setParam (1, phi0, false);
00072   setParam (2, theta, false);
00073   setParam (3, dca, false);
00074   setParam (4, z0, false);
00075   setParam (5, mass, false, true);
00076   setParam (6, sstart, false);
00077   setParam (7, 0, false, true);
00078   // setParam (6, sstop, false);
00079   setMParam (0, pt);
00080   setMParam (1, phi0);
00081   setMParam (2, theta);
00082   setMParam (3, dca);
00083   setMParam (4, z0);
00084   TrackFitObject::initCov();
00085 }
00086 NeutralParticleTrack::NeutralParticleTrack (const char *name_,
00087                                             const ThreeVector& vertex,
00088                                             const ThreeVector& momentum,
00089                                             double mass
00090                                            )
00091 : TrackFitObject (name_) 
00092 {
00093   pt = momentum.getPt();
00094   theta = momentum.getTheta();
00095   phi0 = momentum.getPhi();
00096   
00097 //   cout << "NeutralParticleTrack::NeutralParticleTrack"
00098 //        << "\nvertex = " << vertex << ", momentum = " << momentum
00099 //        << "\npt=" << pt << ", theta=" << theta << ", phi0=" << phi0 << endl;
00100   
00101   sphi0 = sin(phi0);
00102   cphi0 = cos(phi0);
00103   double sstop = vertex.getX()*cphi0 + vertex.getY()*sphi0;
00104   dca = vertex.getX()*sphi0 - vertex.getY()*cphi0; 
00105   z0 = vertex.getZ() - sstop*cos(theta)/sin(theta);
00106 
00107 //   cout << "sstart=" << sstart << ", dca=" << dca << endl;
00108 //   cout << "x(sstart)=" << sstart*cphi0 + dca*sphi0
00109 //        << ", y(sstart)=" << +sstart*sphi0 - dca*cphi0 << endl;
00110   
00111 
00112   setParam (0, pt, false);
00113   setParam (1, phi0, false);
00114   setParam (2, theta, false);
00115   setParam (3, dca, false);
00116   setParam (4, z0, false);
00117   setParam (5, mass, false, true);
00118   setParam (6, 0, false, true);
00119   setParam (7, sstop, false);
00120   
00121 //   printParams (cout);
00122 //   cout << endl << endl;
00123   
00124   setMParam (0, pt);
00125   setMParam (1, phi0);
00126   setMParam (2, theta);
00127   setMParam (3, dca);
00128   setMParam (4, z0);
00129   TrackFitObject::initCov();
00130 }
00131 
00132 NeutralParticleTrack::~NeutralParticleTrack ()
00133 {}
00134 
00135 int NeutralParticleTrack::getNPar() const {
00136   return NPAR;
00137 }
00138 
00139 const char *NeutralParticleTrack::getParamName (int ilocal) const {
00140   switch (ilocal) {
00141     case 0: return "pt";
00142     case 1: return "phi0";
00143     case 2: return "theta";
00144     case 3: return "dca";
00145     case 4: return "z0";
00146     case 5: return "mass";
00147     case 6: return "sstart";
00148     case 7: return "sstop";
00149   }
00150   return "undefined";
00151 }
00152 
00153 bool NeutralParticleTrack::setParam (int ilocal, double par_, 
00154                                  bool measured_, bool fixed_) {
00155   assert (ilocal >= 0 && ilocal < NPAR);
00156   if (measured[ilocal] != measured_ || fixed[ilocal] != fixed_) invalidateCache();
00157   measured[ilocal] = measured_;
00158   fixed[ilocal] = fixed_;
00159   return setParam (ilocal, par_);
00160 };  
00161 
00162 bool NeutralParticleTrack::setParam (int ilocal, double par_ ) {
00163   assert (ilocal >= 0 && ilocal < NPAR);
00164   if (!isfinite(par_)) return false;
00165   // enforce parameter range restrictions
00166   // dont restrict phi0 to -pi ... pi, because otherwise residual calculation
00167   // becomes too complicated!
00168   switch (ilocal) {
00169     case 0:  if (par_ <= 0) return false;
00170       break;
00171     // case 1:  if (abs(par_) > M_PI) par_ = atan2 (sin (par_), cos (par_); // -pi <= phi0 <= pi
00172     //   break;
00173     case 2:  if (par_ < 0 || par_*parfact[2] >= M_PI) par_ = acos (cos (par_*parfact[2]))/parfact[2];
00174       break;
00175     case 5:  if (par_ < 0) par_ = abs (par_);
00176       break;
00177   }
00178   if (par[ilocal] == par_) return true;
00179   invalidateCache();
00180   par[ilocal] = par_;
00181   return true;
00182 };  
00183 
00184 bool NeutralParticleTrack::setParameters (int ivertex, 
00185                                           const ThreeVector& vertex,  
00186                                           const FourVector& momentum,
00187                                           double charge_    
00188                                          ) { 
00189   bool result = true;
00190   pt = momentum.getPt();
00191   theta = momentum.getTheta();
00192   phi0 = momentum.getPhi();
00193   
00194 //   cout << "NeutralParticleTrack::NeutralParticleTrack"
00195 //        << "\nvertex = " << vertex << ", momentum = " << momentum
00196 //        << "\npt=" << pt << ", theta=" << theta << ", phi0=" << phi0 << endl;
00197   
00198   sphi0 = sin(phi0);
00199   cphi0 = cos(phi0);
00200   double s = vertex.getX()*cphi0 + vertex.getY()*sphi0;
00201   dca = vertex.getX()*sphi0 - vertex.getY()*cphi0; 
00202   z0 = vertex.getZ() - s*cos(theta)/sin(theta);
00203 
00204 //   cout << "sstart=" << sstart << ", dca=" << dca << endl;
00205 //   cout << "x(sstart)=" << sstart*cphi0 + dca*sphi0
00206 //        << ", y(sstart)=" << +sstart*sphi0 - dca*cphi0 << endl;
00207   
00208 
00209   if (!isParamFixed (0)) result &= setParam (0, pt/parfact[0]);
00210   if (!isParamFixed (1)) result &= setParam (1, phi0/parfact[1]);
00211   if (!isParamFixed (2)) result &= setParam (2, theta/parfact[2]);
00212   if (!isParamFixed (3)) result &= setParam (3, dca/parfact[3]);
00213   if (!isParamFixed (4)) result &= setParam (4, z0/parfact[4]);
00214   if (!isParamFixed (5)) result &= setParam (5, mass/parfact[5]);
00215   assert (ivertex >= 0 && 6+ivertex < NPAR);
00216   result &= setParam (6+ivertex, s/parfact[6+ivertex]);
00217   return result;
00218 }
00219 
00220 
00221 void NeutralParticleTrack::getTrajectoryPointEx (double s, ThreeVector& p) const {
00222   if (!cachevalid) updateCache();
00223     p.setValues (x0 + cphi0*s,
00224                  y0 + sphi0*s,
00225                  z0 + s*cottheta);
00226 }
00227 
00228 void NeutralParticleTrack::getTrajectoryDerivativeEx (double s, int ilocal, ThreeVector& p) const {
00229   if (!cachevalid) updateCache();
00230   assert (ilocal >= 0 && ilocal < NPAR);
00231   switch (ilocal) {
00232     case 0: // d / d pt
00233       p.setValues (0, 0, 0);          
00234       break;
00235     case 1: // d / d phi0
00236       p.setValues (-y0 - sphi0*s, x0 + cphi0*s, 0);
00237       break;
00238     case 2: // d / d theta
00239       p.setValues (0, 0, - s/sin2theta);          
00240       break;
00241     case 3: // d / d dca
00242       p.setValues (sphi0, -cphi0, 0);          
00243       break;
00244     case 4: // d / d z0
00245       p.setValues (0, 0, 1);  
00246       break;
00247     case 5: // d / d mass
00248       p.setValues (0, 0, 0);  
00249       break;
00250     case 6: // d / d s 
00251             // fall through 
00252     case 7: // d / d s
00253         p.setValues (cphi0, sphi0, cottheta);   
00254       break;
00255     default: // should never happen!
00256       assert (0);
00257   }
00258   p *= parfact[ilocal];
00259 }
00260 
00261 void NeutralParticleTrack::getVertexEx (int ivertex, ThreeVector& p) const {
00262   assert (ivertex >= 0 && 6+ivertex < NPAR);
00263   getTrajectoryPointEx (par[6+ivertex]*parfact[6+ivertex], p);
00264 } 
00265 
00266 void NeutralParticleTrack::setVertex (int ivertex, const TwoVector& p) {
00267   assert (ivertex >= 0 && 6+ivertex < NPAR);
00268   if (!cachevalid) updateCache();
00269   // Get point of closest approach to origin
00270   double xc = sphi0*dca;
00271   double yc = -cphi0*dca;
00272   par[6+ivertex] = ((p.getX()-xc)*cphi0 + (p.getY()-yc)*sphi0)/parfact[6+ivertex];
00273 }
00274 
00275 void NeutralParticleTrack::getVertexDerivativeEx (int ivertex, 
00276                                                   int ilocal, 
00277                                                   ThreeVector& p) const {
00278   assert (ivertex >= 0 && 6+ivertex < NPAR);
00279   assert (ilocal >= 0 && ilocal < NPAR);
00280   // Check: Parameters 5 and 6 are sstart ans sstop.
00281   // Start vertex does not depend on par[7], 
00282   // stop vertex does not depend on par[6]
00283   if (ilocal >= 6 && ilocal != 6+ivertex) {
00284     p.setValues (0, 0, 0);
00285   }
00286   else {
00287     getTrajectoryDerivativeEx (par[6+ivertex]*parfact[6+ivertex], ilocal, p);
00288   }
00289 } 
00290 
00291 void NeutralParticleTrack::getMomentumAtTrajectoryEx (double s, FourVector& p) const {
00292   if (!cachevalid) updateCache();
00293   p.setValues (energy,
00294                px,
00295                py,
00296                pt*cottheta);
00297 }
00298 
00299 void NeutralParticleTrack::getMomentumEx (int ivertex, FourVector& p) const {
00300   assert (ivertex >= 0 && 6+ivertex < NPAR);
00301   getMomentumAtTrajectoryEx (par[6+ivertex]*parfact[6+ivertex], p);
00302 }
00303 
00304 
00305 double NeutralParticleTrack::getCharge () const {
00306   return 0;
00307 } 
00308 
00309 double NeutralParticleTrack::getMass () const {
00310   return  par[5]*parfact[5];
00311 } 
00312 
00313 void NeutralParticleTrack::getMomentumDerivativeAtTrajectoryEx (double s, int ilocal, FourVector& p) const {
00314   if (!cachevalid) updateCache();
00315   assert (ilocal >= 0 && ilocal < getNPar() && ilocal < NPAR);
00316   switch (ilocal) {
00317     case 0: // d / d pt
00318       {
00319         p.setValues (beta/sintheta, cphi0, sphi0, cottheta);
00320       }
00321       break;
00322     case 1: // d / d phi0
00323       p.setValues (0, -py, px, 0);
00324       break;
00325     case 2: // d / d theta
00326       p.setValues (beta*momentum*cottheta,0, 0, -pt/sin2theta);          
00327       break;
00328     case 3: // d / d dca
00329       p.setValues (0, 0, 0, 0);          
00330       break;
00331     case 4: // d / d z0
00332       p.setValues (0, 0, 0, 0);  
00333       break;
00334     case 5: // d / d mass
00335       p.setValues (par[5]/energy, 0, 0, 0);  
00336       break;
00337     case 6: // d / d s 
00338             // fall through 
00339     case 7: // d / d s
00340       p.setValues (0, 0, 0, 0);  
00341       break;
00342     default: // should never happen!
00343       assert (0);
00344   }
00345   p *= parfact[ilocal];
00346 }
00347 
00348 void NeutralParticleTrack::getMomentumDerivativeEx (int ivertex, 
00349                                                 int ilocal, 
00350                                                 FourVector& p) const {
00351   assert (ivertex >= 0 && 6+ivertex < NPAR);
00352   assert (ilocal >= 0 && ilocal < NPAR);
00353   // Check: Parameters 5 and 6 are sstart and sstop.
00354   // Momentum does not depend on them!
00355   if (ilocal >= 6) {
00356     p.setValues (0, 0, 0, 0);
00357   }
00358   else {
00359     getMomentumDerivativeAtTrajectoryEx (par[6+ivertex]*parfact[6+ivertex], ilocal, p);
00360   }
00361 } 
00362 
00363 
00364 double NeutralParticleTrack::getArcLength (int ivertex) const {
00365   assert (ivertex >= 0 && 6+ivertex < NPAR);
00366   return par[6+ivertex]*parfact[6+ivertex];
00367 }
00368 
00369 void NeutralParticleTrack::addToGlobCov(double *glcov, int idim) const {
00370   int globalnum[NPARMAX];
00371   bool ok [NPARMAX];
00372   for (int ilocal = 0; ilocal < getNPar(); ilocal++) {
00373     int iglobal = globalnum[ilocal] = getGlobalParNum(ilocal);
00374     if (ok [iglobal] = (iglobal >= 0 && !isParamFixed(ilocal) && isParamMeasured (ilocal))) {
00375       for (int jlocal = 0; jlocal <= ilocal; jlocal++) {
00376         int jglobal = globalnum[jlocal];
00377         if (ok [jlocal]) {
00378           double c = cov[ilocal][jlocal];
00379           glcov[jglobal+iglobal*idim] += c;
00380           if (jlocal != ilocal) glcov[iglobal+jglobal*idim] += c;
00381         }
00382       }
00383     }
00384   }
00385 } 
00386 
00387 
00388 
00389 void NeutralParticleTrack::updateCache() const {
00390   pt    = par[0]*parfact[0];
00391   phi0  = par[1]*parfact[1];
00392   theta = par[2]*parfact[2];
00393   dca   = par[3]*parfact[3];
00394   z0    = par[4]*parfact[4];
00395   mass  = par[5]*parfact[5];
00396   
00397   sphi0 = sin(phi0);
00398   cphi0 = cos(phi0);
00399   px =  pt*cphi0;
00400   py =  pt*sphi0;
00401   x0 =  dca*sphi0;
00402   y0 = -dca*cphi0;
00403   
00404   sintheta = sin(theta);
00405   cottheta = cos(theta)/sintheta;
00406   sin2theta = sintheta*sintheta;
00407   
00408   momentum = pt/sintheta;
00409      
00410   energy = sqrt(momentum*momentum + mass*mass);
00411   beta =   (energy != 0) ? momentum/energy : 0;      
00412     
00413   calculateChi2();
00414   cachevalid = true;
00415  
00416 }
00417 
00418 void NeutralParticleTrack::initCov(const float cov_[15]) {
00419   TrackFitObject::initCov();
00420 
00421   int i = 0;
00422   for (int k = 0; k < 5; ++k) {
00423     for (int l = k; l < 5; ++l) {
00424       cov[k][l] = cov[l][k] = cov_[i++]/(parfact[k]*parfact[l]);
00425     }
00426   }                         
00427   assert (i==15);
00428   TrackFitObject::checkCov();
00429  
00430   covinvvalid = false;
00431 }
00432 
00433 JBLHelix NeutralParticleTrack::getTangentialHelix (double) {
00434   return JBLHelix (0, 
00435                    par[1]*parfact[1], 
00436                    par[2]*parfact[2], 
00437                    par[3]*parfact[3], 
00438                    par[4]*parfact[4]);
00439 }

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