1 |
#include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistanceHelixLine.h"
|
2 |
#include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
|
3 |
#include "MagneticField/Engine/interface/MagneticField.h"
|
4 |
#include "FWCore/MessageLogger/interface/MessageLogger.h"
|
5 |
#include <iostream>
|
6 |
#include <iomanip>
|
7 |
|
8 |
using namespace std;
|
9 |
|
10 |
bool TwoTrackMinimumDistanceHelixLine::updateCoeffs()
|
11 |
{
|
12 |
|
13 |
if (firstGTP->charge() == 0. && secondGTP->charge() != 0.) {
|
14 |
theL= firstGTP;
|
15 |
theH= secondGTP;
|
16 |
} else if (firstGTP->charge() != 0. && secondGTP->charge() == 0.) {
|
17 |
theH= firstGTP;
|
18 |
theL= secondGTP;
|
19 |
} else {
|
20 |
edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
|
21 |
<< "Error in track charge: "
|
22 |
<< "One of the tracks has to be charged, and the other not." << endl
|
23 |
<< "Track Charges: "<<firstGTP->charge() << " and " <<secondGTP->charge();
|
24 |
return true;
|
25 |
}
|
26 |
|
27 |
Hn = theH->momentum().mag();
|
28 |
Ln = theL->momentum().mag();
|
29 |
|
30 |
if ( Hn == 0. || Ln == 0. )
|
31 |
{
|
32 |
edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
|
33 |
<< "Momentum of input trajectory is zero.";
|
34 |
return true;
|
35 |
};
|
36 |
|
37 |
GlobalPoint lOrig = theL->position();
|
38 |
GlobalPoint hOrig = theH->position();
|
39 |
posDiff = GlobalVector((lOrig - hOrig).basicVector());
|
40 |
X = posDiff.x();
|
41 |
Y = posDiff.y();
|
42 |
Z = posDiff.z();
|
43 |
theLp = theL->momentum();
|
44 |
px = theLp.x(); px2 = px*px;
|
45 |
py = theLp.y(); py2 = py*py;
|
46 |
pz = theLp.z(); pz2 = pz*pz;
|
47 |
|
48 |
const double Bc2kH = theH->magneticField().inTesla(hOrig).z() * 2.99792458e-3;
|
49 |
// MagneticField::inInverseGeV ( hOrig ).z();
|
50 |
|
51 |
if ( Bc2kH == 0. )
|
52 |
{
|
53 |
edm::LogWarning ("TwoTrackMinimumDistanceHelixLine")
|
54 |
<< "Magnetic field at point " << hOrig << " is zero.";
|
55 |
return true;
|
56 |
};
|
57 |
|
58 |
theh= - Hn / (theH->charge() * Bc2kH ) *
|
59 |
sqrt( 1 - ( ( (theH->momentum().z()*theH->momentum().z()) / (Hn*Hn) )));
|
60 |
|
61 |
thetanlambdaH = - theH->momentum().z() / ( theH->charge() * Bc2kH * theh);
|
62 |
|
63 |
thePhiH0 = theH->momentum().phi();
|
64 |
thesinPhiH0= sin(thePhiH0);
|
65 |
thecosPhiH0= cos(thePhiH0);
|
66 |
|
67 |
aa = (X + theh*thesinPhiH0)*(py2 + pz2) - px*(py*Y + pz*Z);
|
68 |
bb = (Y - theh*thecosPhiH0)*(px2 + pz2) - py*(px*X + pz*Z);
|
69 |
cc = pz*theh*thetanlambdaH;
|
70 |
dd = theh* px *py;
|
71 |
ee = theh*(px2 - py2);
|
72 |
ff = (px2 + py2)*theh*thetanlambdaH*thetanlambdaH;
|
73 |
|
74 |
baseFct = thetanlambdaH * (Z*(px2+py2) - pz*(px*X + py*Y));
|
75 |
baseDer = - ff;
|
76 |
return false;
|
77 |
}
|
78 |
|
79 |
bool TwoTrackMinimumDistanceHelixLine::oneIteration(
|
80 |
double & thePhiH, double & fct, double & derivative ) const
|
81 |
{
|
82 |
|
83 |
double thesinPhiH = sin(thePhiH);
|
84 |
double thecosPhiH = cos(thePhiH);
|
85 |
|
86 |
// Fonction of which the root is to be found:
|
87 |
|
88 |
fct = baseFct;
|
89 |
fct -= ff*(thePhiH - thePhiH0);
|
90 |
fct += thecosPhiH * aa;
|
91 |
fct += thesinPhiH * bb;
|
92 |
fct += cc*(thePhiH - thePhiH0)*(px * thecosPhiH + py * thesinPhiH);
|
93 |
fct += cc * (px * (thesinPhiH - thesinPhiH0) - py * (thecosPhiH - thecosPhiH0));
|
94 |
fct += dd * (thesinPhiH* (thesinPhiH - thesinPhiH0) -
|
95 |
thecosPhiH*(thecosPhiH - thecosPhiH0));
|
96 |
fct += ee * thecosPhiH * thesinPhiH;
|
97 |
|
98 |
// Its derivative:
|
99 |
|
100 |
derivative = baseDer;
|
101 |
derivative += - thesinPhiH * aa;
|
102 |
derivative += thecosPhiH * bb;
|
103 |
derivative += cc*(thePhiH - thePhiH0)*(py * thecosPhiH - px * thesinPhiH);
|
104 |
derivative += 2* cc*(px * thecosPhiH + py * thesinPhiH);
|
105 |
derivative += dd *(4 * thecosPhiH * thesinPhiH - thecosPhiH * thesinPhiH0 -
|
106 |
thesinPhiH * thecosPhiH0);
|
107 |
derivative += ee * (thecosPhiH*thecosPhiH-thesinPhiH*thesinPhiH);
|
108 |
|
109 |
return false;
|
110 |
}
|
111 |
|
112 |
bool TwoTrackMinimumDistanceHelixLine::calculate(
|
113 |
const GlobalTrajectoryParameters & theFirstGTP,
|
114 |
const GlobalTrajectoryParameters & theSecondGTP, const float qual )
|
115 |
{
|
116 |
pointsUpdated = false;
|
117 |
firstGTP = (GlobalTrajectoryParameters *) &theFirstGTP;
|
118 |
secondGTP = (GlobalTrajectoryParameters *) &theSecondGTP;
|
119 |
|
120 |
if ( updateCoeffs () )
|
121 |
{
|
122 |
return true;
|
123 |
};
|
124 |
|
125 |
double fctVal, derVal, dPhiH;
|
126 |
thePhiH = thePhiH0;
|
127 |
|
128 |
double x1=thePhiH0-M_PI, x2=thePhiH0+M_PI;
|
129 |
for (int j=1; j<=themaxiter; ++j) {
|
130 |
oneIteration(thePhiH, fctVal, derVal);
|
131 |
dPhiH=fctVal/derVal;
|
132 |
thePhiH -= dPhiH;
|
133 |
if ((x1-thePhiH)*(thePhiH-x2) < 0.0) {
|
134 |
LogDebug ("TwoTrackMinimumDistanceHelixLine")
|
135 |
<< "Jumped out of brackets in root finding. Will be moved closer.";
|
136 |
thePhiH += (dPhiH*0.8);
|
137 |
}
|
138 |
if (fabs(dPhiH) < qual) {return false;}
|
139 |
}
|
140 |
LogDebug ("TwoTrackMinimumDistanceHelixLine")
|
141 |
<<"Number of steps exceeded. Has not converged.";
|
142 |
return true;
|
143 |
}
|
144 |
|
145 |
double TwoTrackMinimumDistanceHelixLine::firstAngle() const
|
146 |
{
|
147 |
if (firstGTP==theL) return theL->momentum().phi();
|
148 |
else return thePhiH;
|
149 |
}
|
150 |
|
151 |
double TwoTrackMinimumDistanceHelixLine::secondAngle() const
|
152 |
{
|
153 |
if (secondGTP==theL) return theL->momentum().phi();
|
154 |
else return thePhiH;
|
155 |
}
|
156 |
|
157 |
pair <GlobalPoint, GlobalPoint> TwoTrackMinimumDistanceHelixLine::points()
|
158 |
const
|
159 |
{
|
160 |
if (!pointsUpdated)finalPoints();
|
161 |
if (firstGTP==theL)
|
162 |
return pair<GlobalPoint, GlobalPoint> (linePoint, helixPoint);
|
163 |
else return pair<GlobalPoint, GlobalPoint> (helixPoint, linePoint);
|
164 |
}
|
165 |
|
166 |
pair <double, double> TwoTrackMinimumDistanceHelixLine::pathLength() const
|
167 |
{
|
168 |
if (!pointsUpdated)finalPoints();
|
169 |
if (firstGTP==theL)
|
170 |
return pair<double, double> (linePath, helixPath);
|
171 |
else return pair<double, double> (helixPath, linePath);
|
172 |
}
|
173 |
|
174 |
void TwoTrackMinimumDistanceHelixLine::finalPoints() const
|
175 |
{
|
176 |
helixPoint = GlobalPoint (
|
177 |
theH->position().x() + theh * ( sin ( thePhiH) - thesinPhiH0 ),
|
178 |
theH->position().y() + theh * ( - cos ( thePhiH) + thecosPhiH0 ),
|
179 |
theH->position().z() + theh * ( thetanlambdaH * ( thePhiH- thePhiH0 ))
|
180 |
);
|
181 |
helixPath = ( thePhiH- thePhiH0 ) * (theh*sqrt(1+thetanlambdaH*thetanlambdaH)) ;
|
182 |
|
183 |
GlobalVector diff((theL->position() -helixPoint).basicVector());
|
184 |
tL = ( - diff.dot(theLp)) / (Ln*Ln);
|
185 |
linePoint = GlobalPoint (
|
186 |
theL->position().x() + tL * px,
|
187 |
theL->position().y() + tL * py,
|
188 |
theL->position().z() + tL * pz );
|
189 |
linePath = tL * theLp.mag();
|
190 |
pointsUpdated = true;
|
191 |
}
|