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.basicVector() - b.basicVector() );
00012 }
00013
00014 inline GlobalPoint operator + ( const GlobalPoint & a, const GlobalPoint & b ){
00015 return GlobalPoint ( a.basicVector() + b.basicVector() );
00016 }
00017
00018 inline GlobalPoint operator / ( const GlobalPoint & a, const double b ){
00019 return GlobalPoint ( a.basicVector() / b );
00020 }
00021
00022 inline GlobalPoint operator * ( const GlobalPoint & a, const float b ){
00023 return GlobalPoint ( a.basicVector() * b );
00024 }
00025
00026 inline GlobalPoint operator * ( const float b , const GlobalPoint & a ){
00027 return GlobalPoint ( a.basicVector() * b );
00028 }
00029
00030 inline double square ( const double s ) { return s*s; }
00031 }
00032
00033 TwoTrackMinimumDistanceHelixHelix::TwoTrackMinimumDistanceHelixHelix():
00034 theH(0), theG(0), pointsUpdated(false), themaxjump(20),thesingjacI(1./0.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 = theH->magneticField().inInverseGeV(gpH).z();
00043 const double Bc2kG = theG->magneticField().inInverseGeV(gpG).z();
00044 const double Ht= theH->momentum().perp();
00045 const double Gt= theG->momentum().perp();
00046
00047
00048 if ( Ht == 0. || Gt == 0. ) {
00049 edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00050 << "transverse momentum of input trajectory is zero.";
00051 return true;
00052 };
00053
00054 if ( theH->charge() == 0. || theG->charge() == 0. ) {
00055 edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00056 << "charge of input track is zero.";
00057 return true;
00058 };
00059
00060 if ( Bc2kG == 0.) {
00061 edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00062 << "magnetic field at point " << gpG << " is zero.";
00063 return true;
00064 };
00065
00066 if ( Bc2kH == 0. ) {
00067 edm::LogWarning ("TwoTrackMinimumDistanceHelixHelix")
00068 << "magnetic field at point " << gpH << " is zero.";
00069 return true;
00070 };
00071
00072 theh= Ht / (theH->charge() * Bc2kH );
00073 thesinpH0= - theH->momentum().y() / ( Ht );
00074 thecospH0= - theH->momentum().x() / ( Ht );
00075 thetanlambdaH = - theH->momentum().z() / ( Ht);
00076 thepH0 = atan2 ( thesinpH0 , thecospH0 );
00077
00078
00079
00080 theg= Gt / (theG->charge() * Bc2kG );
00081 thesinpG0= - theG->momentum().y() / ( Gt);
00082 thecospG0= - theG->momentum().x() / (Gt);
00083 thetanlambdaG = - theG->momentum().z() / ( Gt);
00084 thepG0 = atan2 ( thesinpG0 , thecospG0 );
00085
00086 thea=theH->position().x() - theG->position().x() + theg * thesinpG0 -
00087 theh * thesinpH0;
00088 theb=theH->position().y() - theG->position().y() - theg * thecospG0 +
00089 theh * thecospH0;
00090 thec1= theh * thetanlambdaH * thetanlambdaH;
00091 thec2= -theg * thetanlambdaG * thetanlambdaG;
00092 thed1= -theg * thetanlambdaG * thetanlambdaH;
00093 thed2= theh * thetanlambdaG * thetanlambdaH;
00094 thee1= thetanlambdaH * ( theH->position().z() - theG->position().z() -
00095 theh * thepH0 * thetanlambdaH + theg * thepG0 * thetanlambdaG );
00096 thee2= thetanlambdaG * ( theH->position().z() - theG->position().z() -
00097 theh * thepH0 * thetanlambdaH + theg * thepG0 * thetanlambdaG );
00098 return false;
00099 }
00100
00101 bool TwoTrackMinimumDistanceHelixHelix::oneIteration(double & dH, double & dG ) const {
00102 thesinpH=sin(thepH);
00103 thecospH=cos(thepH);
00104 thesinpG=sin(thepG);
00105 thecospG=cos(thepG);
00106
00107 const double A11= theh * ( - thesinpH * ( thea - theg * thesinpG ) +
00108 thecospH * ( theb + theg * thecospG ) + thec1);
00109 if (A11 < 0) { return true; };
00110 const double A22= -theg * (- thesinpG * ( thea + theh * thesinpH ) +
00111 thecospG*( theb - theh * thecospH ) + thec2);
00112 if (A22 < 0) { return true; };
00113 const double A12= theh * (-theg * thecospG * thecospH -
00114 theg * thesinpH * thesinpG + thed1);
00115 const double A21= -theg * (theh * thecospG * thecospH +
00116 theh * thesinpH * thesinpG + thed2);
00117 const double detaI = 1./(A11 * A22 - A12 * A21);
00118 const double z1=theh * ( thecospH * ( thea - theg * thesinpG ) + thesinpH *
00119 ( theb + theg*thecospG ) + thec1 * thepH + thed1 * thepG + thee1);
00120 const double z2=-theg * (thecospG * ( thea + theh * thesinpH ) + thesinpG *
00121 ( theb - theh*thecospH ) + thec2 * thepG + thed2 * thepH + thee2);
00122
00123 dH=( z1 * A22 - z2 * A12 ) * detaI;
00124 dG=( z2 * A11 - z1 * A21 ) * detaI;
00125 if ( fabs(detaI) > thesingjacI ) { return true; };
00126
00127 thepH -= dH;
00128 thepG -= dG;
00129 return false;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 bool TwoTrackMinimumDistanceHelixHelix::calculate(
00143 const GlobalTrajectoryParameters & G,
00144 const GlobalTrajectoryParameters & H, const float qual ) {
00145 pointsUpdated = false;
00146 theG= &G;
00147 theH= &H;
00148 bool retval=false;
00149
00150 if ( updateCoeffs ( theG->position(), theH->position() ) ) return true;
00151
00152 thepG = thepG0;
00153 thepH = thepH0;
00154
00155 int counter=0;
00156 double pH=0; double pG=0;
00157 do {
00158 retval=oneIteration ( pG, pH );
00159 if ( std::isinf(pG) || std::isinf(pH) ) retval=true;
00160 if ( counter++>themaxiter ) retval=true;
00161 } while ( (!retval) && ( fabs(pG) > qual || fabs(pH) > qual ));
00162 if ( fabs ( theg * ( thepG - thepG0 ) ) > themaxjump ) retval=true;
00163 if ( fabs ( theh * ( thepH - thepH0 ) ) > themaxjump ) retval=true;
00164 return retval;
00165 }
00166
00167
00168 void TwoTrackMinimumDistanceHelixHelix::finalPoints() const {
00169 GlobalVector tmpG( sin(thepG) - thesinpG0,
00170 - cos(thepG) + thecospG0,
00171 thetanlambdaG * ( thepG- thepG0 )
00172 );
00173 pointG = theG->position() + theg * tmpG;
00174 pathG = ( thepG- thepG0 ) * (theg*sqrt(1+thetanlambdaG*thetanlambdaG)) ;
00175
00176 GlobalVector tmpH( sin(thepH) - thesinpH0,
00177 - cos(thepH) + thecospH0,
00178 thetanlambdaH * ( thepH- thepH0 )
00179 );
00180 pointH = theH->position() + theh * tmpH;
00181 pathH = ( thepH- thepH0 ) * (theh*sqrt(1+thetanlambdaH*thetanlambdaH)) ;
00182
00183 pointsUpdated = true;
00184 }
00185