CMS 3D CMS Logo

TwoTrackMinimumDistanceHelixHelix.cc

Go to the documentation of this file.
00001 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistanceHelixHelix.h"
00002 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00003 #include "MagneticField/Engine/interface/MagneticField.h"
00004 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 
00007 using namespace std;
00008 
00009 namespace {
00010   inline GlobalPoint operator - ( const GlobalPoint & a, const GlobalPoint & b ){
00011     return GlobalPoint ( a.x() - b.x(), a.y() - b.y(), a.z() - b.z() );
00012   }
00013 
00014   inline GlobalPoint operator + ( const GlobalPoint & a, const GlobalPoint & b ){
00015     return GlobalPoint ( a.x() + b.x(), a.y() + b.y(), a.z() + b.z() );
00016   }
00017 
00018   inline GlobalPoint operator / ( const GlobalPoint & a, const double b ){
00019     return GlobalPoint ( a.x() / b, a.y() / b, a.z() / b );
00020   }
00021 
00022   inline GlobalPoint operator * ( const GlobalPoint & a, const double b ){
00023     return GlobalPoint ( a.x() * b, a.y() * b, a.z() * b );
00024   }
00025 
00026   inline GlobalPoint operator * ( const double b , const GlobalPoint & a ){
00027     return GlobalPoint ( a.x() * b, a.y() * b, a.z() * b );
00028   }
00029 
00030   inline double square ( const double s ) { return s*s; }
00031 }
00032 
00033 TwoTrackMinimumDistanceHelixHelix::TwoTrackMinimumDistanceHelixHelix():
00034 theH(), theG(), pointsUpdated(false), themaxjump(20),thesingjac(.1), themaxiter(4)
00035 { }
00036 
00037 TwoTrackMinimumDistanceHelixHelix::~TwoTrackMinimumDistanceHelixHelix() {}
00038 
00039 bool TwoTrackMinimumDistanceHelixHelix::updateCoeffs(
00040     const GlobalPoint & gpH, const GlobalPoint & gpG )
00041 {
00042 //  const double Bc2kH = MagneticField::inInverseGeV ( gpH ).z();
00043   const double Bc2kH = theH->magneticField().inTesla(gpH).z() * 2.99792458e-3;
00044 //  const double Bc2kG = MagneticField::inInverseGeV ( gpG ).z();
00045   const double Bc2kG = theG->magneticField().inTesla(gpG).z() * 2.99792458e-3;
00046   const double Hn= theH->momentum().mag();
00047   const double Gn= theG->momentum().mag();
00048   thelambdaH=asin ( theH->momentum().z() / Hn );
00049 
00050   if ( Hn == 0. || Gn == 0. )
00051   {
00052     edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00053       << "momentum of input trajectory is zero.";
00054     return true;
00055   };
00056 
00057   if ( theH->charge() == 0. || theG->charge() == 0. )
00058   {
00059     edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00060       << "charge of input track is zero.";
00061     return true;
00062   };
00063 
00064   if ( Bc2kG == 0. )
00065   {
00066     edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00067       << "magnetic field at point " << gpG << " is zero.";
00068     return true;
00069   };
00070 
00071   if ( Bc2kH == 0. )
00072   {
00073     edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00074       << "magnetic field at point " << gpH << " is zero.";
00075     return true;
00076   };
00077 
00078   theh= Hn / (theH->charge() * Bc2kH ) *
00079      sqrt( 1 - square ( ( theH->momentum().z() / Hn )));
00080   thesinpH0= - theH->momentum().y() / ( theH->charge() * Bc2kH * theh );
00081   thecospH0= - theH->momentum().x() / ( theH->charge() * Bc2kH * theh );
00082   thetanlambdaH = - theH->momentum().z() / ( theH->charge() * Bc2kH * theh);
00083   thepH0 = atan2 ( thesinpH0 , thecospH0 );
00084   thelambdaG=asin ( theG->momentum().z()/( Gn ) );
00085   theg= Gn / (theG->charge() * Bc2kG ) *
00086     sqrt( 1 - square ( ( theG->momentum().z() / Gn )));
00087   thesinpG0= - theG->momentum().y() / ( theG->charge()* Bc2kG * theg );
00088   thecospG0= - theG->momentum().x() / ( theG->charge() * Bc2kG * theg );
00089   thetanlambdaG = - theG->momentum().z() / ( theG->charge() * Bc2kG * theg);
00090 
00091   thepG0 = atan2 ( thesinpG0 , thecospG0 );
00092 
00093   thea=theH->position().x() - theG->position().x() + theg * thesinpG0 -
00094      theh * thesinpH0;
00095   theb=theH->position().y() - theG->position().y() - theg * thecospG0 +
00096      theh * thecospH0;
00097   thec1= theh * thetanlambdaH * thetanlambdaH;
00098   thec2= -theg * thetanlambdaG * thetanlambdaG;
00099   thed1= -theg * thetanlambdaG * thetanlambdaH;
00100   thed2= theh * thetanlambdaG * thetanlambdaH;
00101   thee1= thetanlambdaH * ( theH->position().z() - theG->position().z() -
00102        theh * thepH0 * thetanlambdaH + theg * thepG0 * thetanlambdaG );
00103   thee2= thetanlambdaG * ( theH->position().z() - theG->position().z() -
00104        theh * thepH0 * thetanlambdaH + theg * thepG0 * thetanlambdaG );
00105   return false;
00106 }
00107 
00108 bool TwoTrackMinimumDistanceHelixHelix::oneIteration(
00109     double & dH, double & dG ) const
00110 {
00111   thesinpH=sin(thepH);
00112   thecospH=cos(thepH);
00113   thesinpG=sin(thepG);
00114   thecospG=cos(thepG);
00115 
00116   const double A11= theh * ( - thesinpH * ( thea - theg * thesinpG ) +
00117       thecospH * ( theb + theg * thecospG ) + thec1);
00118   if (A11 < 0) { return true; };
00119   const double A22= -theg * (- thesinpG * ( thea + theh * thesinpH ) +
00120       thecospG*( theb - theh * thecospH ) + thec2);
00121   if (A22 < 0) { return true; };
00122   const double A12= theh * (-theg * thecospG * thecospH -
00123       theg * thesinpH * thesinpG + thed1);
00124   const double A21= -theg * (theh * thecospG * thecospH +
00125       theh * thesinpH * thesinpG + thed2);
00126   const double deta = A11 * A22 - A12 * A21;
00127   const double z1=theh * ( thecospH * ( thea - theg * thesinpG ) + thesinpH *
00128       ( theb + theg*thecospG ) + thec1 * thepH + thed1 * thepG + thee1);
00129   const double z2=-theg * (thecospG * ( thea + theh * thesinpH ) + thesinpG *
00130       ( theb - theh*thecospH ) + thec2 * thepG + thed2 * thepH + thee2);
00131   
00132   dH=( z1 * A22 - z2 * A12 ) / deta;
00133   dG=( z2 * A11 - z1 * A21 ) / deta;
00134   if ( fabs(deta) < thesingjac ) { return true; };
00135 
00136   thepH -= dH;
00137   thepG -= dG;
00138   return false;
00139 }
00140 
00141 inline bool TwoTrackMinimumDistanceHelixHelix::parallelTracks() const
00142 {
00143   bool retval=false;
00144   if (fabs(theH->momentum().x() - theG->momentum().x()) < .00000001 )
00145   if (fabs(theH->momentum().y() - theG->momentum().y()) < .00000001 )
00146   if (fabs(theH->momentum().z() - theG->momentum().z()) < .00000001 )
00147   if (theH->charge()==theG->charge()) retval=true;
00148   return retval;
00149 }
00150 
00151 
00152 bool TwoTrackMinimumDistanceHelixHelix::calculate(
00153     const GlobalTrajectoryParameters & G,
00154     const GlobalTrajectoryParameters & H, const float qual )
00155 {
00156   pointsUpdated = false;
00157   theG= (GlobalTrajectoryParameters *) &G;
00158   theH= (GlobalTrajectoryParameters *) &H;
00159   bool retval=false;
00160 
00161   if ( updateCoeffs ( theG->position(), theH->position() ) )
00162   {
00163     return true;
00164   };
00165 
00166   thepG = thepG0;
00167   thepH = thepH0;
00168 
00169   int counter=0;
00170   double pH=0; double pG=0;
00171   do {
00172     retval=oneIteration ( pG, pH );
00173     if ( !finite(pG) || !finite(pH) ) retval=true;
00174     if ( counter++>themaxiter ) retval=true;
00175   } while ( (!retval) && ( fabs(pG) > qual || fabs(pH) > qual ));
00176   if ( fabs ( theg * ( thepG - thepG0 ) ) > themaxjump ) retval=true;
00177   if ( fabs ( theh * ( thepH - thepH0 ) ) > themaxjump ) retval=true;
00178   return retval;
00179 }
00180 
00181 double TwoTrackMinimumDistanceHelixHelix::firstAngle()  const
00182 {
00183   return thepG;
00184 }
00185 
00186 double TwoTrackMinimumDistanceHelixHelix::secondAngle() const
00187 {
00188   return thepH;
00189 }
00190 
00191 void TwoTrackMinimumDistanceHelixHelix::finalPoints() const
00192 {
00193   pointG = GlobalPoint (
00194       theG->position().x() + theg * ( sin ( thepG) - thesinpG0) ,
00195       theG->position().y() + theg * ( - cos ( thepG) + thecospG0 ),
00196       theG->position().z() + theg * ( thetanlambdaG * ( thepG- thepG0 ))
00197   );
00198   pathG = ( thepG- thepG0 ) * (theg*sqrt(1+thetanlambdaG*thetanlambdaG)) ;
00199 
00200   pointH = GlobalPoint (
00201       theH->position().x() + theh * ( sin ( thepH) - thesinpH0 ),
00202       theH->position().y() + theh * ( - cos ( thepH) + thecospH0 ),
00203       theH->position().z() + theh * ( thetanlambdaH * ( thepH- thepH0 ))
00204   );
00205   pathH = ( thepH- thepH0 ) * (theh*sqrt(1+thetanlambdaH*thetanlambdaH)) ;
00206   pointsUpdated = true;
00207 }
00208 
00209 pair <double, double> TwoTrackMinimumDistanceHelixHelix::pathLength() const
00210 {
00211   if (!pointsUpdated)finalPoints();
00212   return pair <double, double> ( pathG, pathH);
00213 }
00214 
00215 pair <GlobalPoint, GlobalPoint> TwoTrackMinimumDistanceHelixHelix::points()
00216     const 
00217 {
00218   if (!pointsUpdated)finalPoints();
00219   return pair<GlobalPoint, GlobalPoint> (pointG, pointH);
00220 }
00221 

Generated on Tue Jun 9 17:48:27 2009 for CMSSW by  doxygen 1.5.4