CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/TrackingTools/PatternTools/src/TwoTrackMinimumDistanceHelixLine.cc

Go to the documentation of this file.
00001 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistanceHelixLine.h"
00002 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00003 #include "MagneticField/Engine/interface/MagneticField.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include <iostream>
00006 #include <iomanip>
00007 
00008 using namespace std;
00009 
00010 bool TwoTrackMinimumDistanceHelixLine::updateCoeffs()
00011 {
00012   bool isFirstALine = firstGTP->charge() == 0. || firstGTP->magneticField().inTesla(firstGTP->position()).z() == 0.;
00013   bool isSecondALine = secondGTP->charge() == 0. || secondGTP->magneticField().inTesla(secondGTP->position()).z() == 0.;
00014   if (isFirstALine && !isSecondALine ) {
00015     theL= firstGTP;
00016     theH= secondGTP;
00017   } else if (!isFirstALine && isSecondALine) {
00018     theH= firstGTP;
00019     theL= secondGTP;
00020   } else {
00021     edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
00022       << "Error in track charge: "
00023       << "One of the tracks has to be charged, and the other not." << endl
00024       << "Track Charges: "<<firstGTP->charge() << " and " <<secondGTP->charge();
00025     return true;
00026   }
00027 
00028   Hn = theH->momentum().mag();
00029   Ln = theL->momentum().mag();
00030 
00031   if ( Hn == 0. || Ln == 0. )
00032   {
00033     edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
00034       << "Momentum of input trajectory is zero.";
00035     return true;
00036   };
00037 
00038   GlobalPoint lOrig = theL->position();
00039   GlobalPoint hOrig = theH->position();
00040   posDiff = GlobalVector((lOrig - hOrig).basicVector());
00041   X = posDiff.x();
00042   Y = posDiff.y();
00043   Z = posDiff.z();
00044   theLp = theL->momentum();
00045   px = theLp.x(); px2 = px*px;
00046   py = theLp.y(); py2 = py*py;
00047   pz = theLp.z(); pz2 = pz*pz;
00048   
00049   const double Bc2kH = theH->magneticField().inTesla(hOrig).z() * 2.99792458e-3;
00050 //   MagneticField::inInverseGeV ( hOrig ).z();
00051 
00052   if ( Bc2kH == 0. )
00053   {
00054     edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
00055       << "Magnetic field at point " << hOrig << " is zero.";
00056     return true;
00057   };
00058 
00059   theh= - Hn / (theH->charge() * Bc2kH ) *
00060      sqrt( 1 - ( ( (theH->momentum().z()*theH->momentum().z()) / (Hn*Hn) )));
00061 
00062   thetanlambdaH = - theH->momentum().z() / ( theH->charge() * Bc2kH * theh);
00063 
00064   thePhiH0 = theH->momentum().phi();
00065   thesinPhiH0= sin(thePhiH0);
00066   thecosPhiH0= cos(thePhiH0);
00067 
00068   aa = (X + theh*thesinPhiH0)*(py2 + pz2) - px*(py*Y + pz*Z);
00069   bb = (Y - theh*thecosPhiH0)*(px2 + pz2) - py*(px*X + pz*Z);
00070   cc = pz*theh*thetanlambdaH;
00071   dd = theh* px *py;
00072   ee = theh*(px2 - py2);
00073   ff = (px2 + py2)*theh*thetanlambdaH*thetanlambdaH;
00074 
00075   baseFct = thetanlambdaH * (Z*(px2+py2) - pz*(px*X + py*Y));
00076   baseDer = - ff;
00077   return false;
00078 }
00079 
00080 bool TwoTrackMinimumDistanceHelixLine::oneIteration(
00081     double & thePhiH, double & fct, double & derivative ) const
00082 {
00083 
00084   double thesinPhiH = sin(thePhiH);
00085   double thecosPhiH = cos(thePhiH);
00086 
00087         // Fonction of which the root is to be found:
00088 
00089   fct = baseFct;
00090   fct -= ff*(thePhiH - thePhiH0);
00091   fct += thecosPhiH * aa;
00092   fct += thesinPhiH * bb;
00093   fct += cc*(thePhiH - thePhiH0)*(px * thecosPhiH + py * thesinPhiH);
00094   fct += cc * (px * (thesinPhiH - thesinPhiH0) - py * (thecosPhiH - thecosPhiH0));
00095   fct += dd * (thesinPhiH* (thesinPhiH - thesinPhiH0) - 
00096                 thecosPhiH*(thecosPhiH - thecosPhiH0));
00097   fct += ee * thecosPhiH * thesinPhiH;
00098 
00099           // Its derivative:
00100 
00101   derivative = baseDer;
00102   derivative += - thesinPhiH * aa;
00103   derivative += thecosPhiH * bb;
00104   derivative += cc*(thePhiH - thePhiH0)*(py * thecosPhiH - px * thesinPhiH);
00105   derivative += 2* cc*(px * thecosPhiH + py * thesinPhiH);
00106   derivative += dd *(4 * thecosPhiH * thesinPhiH - thecosPhiH * thesinPhiH0 - 
00107                         thesinPhiH * thecosPhiH0);
00108   derivative += ee * (thecosPhiH*thecosPhiH-thesinPhiH*thesinPhiH);
00109 
00110   return false;
00111 }
00112 
00113 bool TwoTrackMinimumDistanceHelixLine::calculate(
00114     const GlobalTrajectoryParameters & theFirstGTP,
00115     const GlobalTrajectoryParameters & theSecondGTP, const float qual )
00116 {
00117   pointsUpdated = false;
00118   firstGTP  = (GlobalTrajectoryParameters *) &theFirstGTP;
00119   secondGTP = (GlobalTrajectoryParameters *) &theSecondGTP;
00120 
00121   if ( updateCoeffs () )
00122   {
00123     return true;
00124   };
00125 
00126   double fctVal, derVal, dPhiH;
00127   thePhiH = thePhiH0;
00128   
00129   double x1=thePhiH0-M_PI, x2=thePhiH0+M_PI;
00130   for (int j=1; j<=themaxiter; ++j) { 
00131     oneIteration(thePhiH, fctVal, derVal);
00132     dPhiH=fctVal/derVal;
00133     thePhiH -= dPhiH;
00134     if ((x1-thePhiH)*(thePhiH-x2) < 0.0) {
00135       LogDebug ("TwoTrackMinimumDistanceHelixLine")
00136         << "Jumped out of brackets in root finding. Will be moved closer.";
00137       thePhiH += (dPhiH*0.8);
00138     }
00139     if (fabs(dPhiH) < qual) {return false;}
00140   }
00141   LogDebug ("TwoTrackMinimumDistanceHelixLine")
00142     <<"Number of steps exceeded. Has not converged.";
00143   return true;
00144 }
00145 
00146 double TwoTrackMinimumDistanceHelixLine::firstAngle()  const
00147 {
00148   if (firstGTP==theL) return theL->momentum().phi();
00149   else return thePhiH;
00150 }
00151 
00152 double TwoTrackMinimumDistanceHelixLine::secondAngle() const
00153 {
00154   if (secondGTP==theL) return theL->momentum().phi();
00155   else return thePhiH;
00156 }
00157 
00158 pair <GlobalPoint, GlobalPoint> TwoTrackMinimumDistanceHelixLine::points()
00159     const 
00160 {
00161   if (!pointsUpdated)finalPoints();
00162   if (firstGTP==theL) 
00163     return pair<GlobalPoint, GlobalPoint> (linePoint, helixPoint);
00164   else return pair<GlobalPoint, GlobalPoint> (helixPoint, linePoint);
00165 }
00166 
00167 pair <double, double> TwoTrackMinimumDistanceHelixLine::pathLength() const
00168 {
00169   if (!pointsUpdated)finalPoints();
00170   if (firstGTP==theL) 
00171     return pair<double, double> (linePath, helixPath);
00172   else return pair<double, double> (helixPath, linePath);
00173 }
00174 
00175 void TwoTrackMinimumDistanceHelixLine::finalPoints() const
00176 {
00177   helixPoint = GlobalPoint (
00178       theH->position().x() + theh * ( sin ( thePhiH) - thesinPhiH0 ),
00179       theH->position().y() + theh * ( - cos ( thePhiH) + thecosPhiH0 ),
00180       theH->position().z() + theh * ( thetanlambdaH * ( thePhiH- thePhiH0 ))
00181   );
00182   helixPath = ( thePhiH- thePhiH0 ) * (theh*sqrt(1+thetanlambdaH*thetanlambdaH)) ;
00183 
00184   GlobalVector diff((theL->position() -helixPoint).basicVector());
00185   tL = ( - diff.dot(theLp)) / (Ln*Ln);
00186   linePoint = GlobalPoint (
00187       theL->position().x() + tL * px,
00188       theL->position().y() + tL * py,
00189       theL->position().z() + tL * pz );
00190   linePath = tL * theLp.mag();
00191   pointsUpdated = true;
00192 }