ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/IPHCalignment2/TrackingTools/TrajectoryState/src/PerigeeConversions.cc
Revision: 1.1
Committed: Fri Nov 25 16:38:28 2011 UTC (13 years, 5 months ago) by econte
Content type: text/plain
Branch: MAIN
CVS Tags: TBD2011, TBD_2011, HEAD
Error occurred while calculating annotation data.
Log Message:
new IPHC alignment

File Contents

# Content
1 #include "TrackingTools/TrajectoryState/interface/PerigeeConversions.h"
2 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToPoint.h"
3 #include "MagneticField/Engine/interface/MagneticField.h"
4 #include <cmath>
5
6 PerigeeTrajectoryParameters PerigeeConversions::ftsToPerigeeParameters
7 (const FTS& originalFTS, const GlobalPoint& referencePoint, double & pt) const
8
9 {
10 GlobalVector impactDistance = originalFTS.position() - referencePoint;
11
12 pt = originalFTS.momentum().perp();
13 if (pt==0.) throw cms::Exception("PerigeeConversions", "Track with pt=0");
14
15 double theta = originalFTS.momentum().theta();
16 double phi = originalFTS.momentum().phi();
17 double field = originalFTS.parameters().magneticField().inInverseGeV(originalFTS.position()).z();
18 // if (field==0.) throw cms::Exception("PerigeeConversions", "Field is 0") << " at " << originalFTS.position() << "\n" ;
19
20 double positiveMomentumPhi = ( (phi>0) ? phi : (2*M_PI+phi) );
21 double positionPhi = impactDistance.phi();
22 double positivePositionPhi =
23 ( (positionPhi>0) ? positionPhi : (2*M_PI+positionPhi) );
24 double phiDiff = positiveMomentumPhi - positivePositionPhi;
25 if (phiDiff<0.0) phiDiff+= (2*M_PI);
26 double signEpsilon = ( (phiDiff > M_PI) ? -1.0 : 1.0);
27
28 double epsilon = signEpsilon *
29 sqrt ( impactDistance.x()*impactDistance.x() +
30 impactDistance.y()*impactDistance.y() );
31
32 // The track parameters:
33 AlgebraicVector5 theTrackParameters;
34
35 double signTC = - originalFTS.charge();
36 bool isCharged = (signTC!=0) && (fabs(field)>1.e-10);
37 if (isCharged) {
38 theTrackParameters[0] = field / pt*signTC;
39 } else {
40 theTrackParameters[0] = 1 / pt;
41 }
42 theTrackParameters[1] = theta;
43 theTrackParameters[2] = phi;
44 theTrackParameters[3] = epsilon;
45 theTrackParameters[4] = impactDistance.z();
46 return PerigeeTrajectoryParameters(theTrackParameters, isCharged);
47 }
48
49 // PerigeeTrajectoryParameters PerigeeConversions::helixToPerigeeParameters
50 // (const reco::helix::Parameters & helixPar, const GlobalPoint& referencePoint) const
51 // {
52 // AlgebraicVector theTrackParameters = AlgebraicVector(5);
53 // double field = TrackingTools::FakeField::Field::inTesla(helixPar.vertex()).z() * 2.99792458e-3;
54 // theTrackParameters[0] = - field*helixPar.omega();
55 // theTrackParameters[1] = atan(1/helixPar.tanDip());
56 // theTrackParameters[2] = helixPar.phi0() - M_PI/2;
57 // theTrackParameters[3] = helixPar.d0();
58 // theTrackParameters[4] = helixPar.dz();
59 // return PerigeeTrajectoryParameters(theTrackParameters, helixPar.pt(), true);
60 // }
61
62 PerigeeTrajectoryError PerigeeConversions::ftsToPerigeeError
63 (const FTS& originalFTS) const
64 {
65 AlgebraicSymMatrix55 errorMatrix = originalFTS.curvilinearError().matrix();
66 AlgebraicMatrix55 curv2perigee = jacobianCurvilinear2Perigee(originalFTS);
67 return PerigeeTrajectoryError(ROOT::Math::Similarity(curv2perigee,errorMatrix));
68 }
69
70 // PerigeeTrajectoryError PerigeeConversions::helixToPerigeeError
71 // (const reco::helix::Parameters & helixPar,
72 // const reco::helix::Covariance & helixCov) const
73 // {
74 // //FIXME: verify that the order of the parameters are correct
75 // AlgebraicSymMatrix55 helixCovMatrix;
76 // helixCovMatrix(0,0) = helixCov(reco::helix::i_d0,reco::helix::i_d0);
77 // helixCovMatrix(1,1) = helixCov(reco::helix::i_phi0,reco::helix::i_phi0);
78 // helixCovMatrix(2,2) = helixCov(reco::helix::i_omega,reco::helix::i_omega);
79 // helixCovMatrix(3,3) = helixCov(reco::helix::i_dz,reco::helix::i_dz);
80 // helixCovMatrix(4,4) = helixCov(reco::helix::i_tanDip,reco::helix::i_tanDip);
81 //
82 // helixCovMatrix(0,1) = helixCov(reco::helix::i_d0,reco::helix::i_phi0);
83 // helixCovMatrix(0,2) = helixCov(reco::helix::i_d0,reco::helix::i_omega);
84 // helixCovMatrix(0,3) = helixCov(reco::helix::i_d0,reco::helix::i_dz);
85 // helixCovMatrix(0,4) = helixCov(reco::helix::i_d0,reco::helix::i_tanDip);
86 //
87 // helixCovMatrix(1,2) = helixCov(reco::helix::i_phi0,reco::helix::i_omega);
88 // helixCovMatrix(1,3) = helixCov(reco::helix::i_phi0,reco::helix::i_dz);
89 // helixCovMatrix(1,4) = helixCov(reco::helix::i_phi0,reco::helix::i_tanDip);
90 //
91 // helixCovMatrix(2,3) = helixCov(reco::helix::i_omega,reco::helix::i_dz);
92 // helixCovMatrix(2,4) = helixCov(reco::helix::i_omega,reco::helix::i_tanDip);
93 //
94 // helixCovMatrix(3,4) = helixCov(reco::helix::i_dz,reco::helix::i_tanDip);
95 //
96 // AlgebraicMatrix helix2perigee = jacobianHelix2Perigee(helixPar, helixCov);
97 // return PerigeeTrajectoryError(helixCovMatrix.similarity(helix2perigee));
98 // }
99
100
101 CurvilinearTrajectoryError PerigeeConversions::curvilinearError
102 (const PerigeeTrajectoryError& perigeeError, const GlobalTrajectoryParameters& gtp) const
103 {
104 AlgebraicMatrix55 perigee2curv = jacobianPerigee2Curvilinear(gtp);
105 return CurvilinearTrajectoryError(ROOT::Math::Similarity(perigee2curv, perigeeError.covarianceMatrix()));
106 }
107
108 GlobalPoint PerigeeConversions::positionFromPerigee
109 (const PerigeeTrajectoryParameters& parameters, const GlobalPoint& referencePoint) const
110 {
111 AlgebraicVector5 theVector = parameters.vector();
112 return GlobalPoint(theVector[3]*sin(theVector[2])+referencePoint.x(),
113 -theVector[3]*cos(theVector[2])+referencePoint.y(),
114 theVector[4]+referencePoint.z());
115 }
116
117
118 GlobalVector PerigeeConversions::momentumFromPerigee
119 (const PerigeeTrajectoryParameters& parameters, double pt, const GlobalPoint& referencePoint) const
120 {
121 return GlobalVector(cos(parameters.phi()) * pt,
122 sin(parameters.phi()) * pt,
123 pt / tan(parameters.theta()));
124 }
125
126
127 GlobalVector PerigeeConversions::momentumFromPerigee
128 (const AlgebraicVector3& momentum, const TrackCharge& charge,
129 const GlobalPoint& referencePoint, const MagneticField* field) const
130 {
131 double pt;
132 if (momentum[0]==0.) throw cms::Exception("PerigeeConversions", "Track with rho=0");
133
134 double bz = fabs(field->inInverseGeV(referencePoint).z());
135 if ( charge!=0 && bz>1.e-10 ) {
136 pt = std::abs(bz/momentum[0]);
137 if (pt<1.e-10) throw cms::Exception("PerigeeConversions", "pt is 0");
138 } else {
139 pt = 1 / momentum[0];
140 }
141
142 return GlobalVector(cos(momentum[2]) * pt,
143 sin(momentum[2]) * pt,
144 pt/tan(momentum[1]));
145 }
146
147 TrackCharge PerigeeConversions::chargeFromPerigee
148 (const PerigeeTrajectoryParameters& parameters) const
149 {
150 return parameters.charge();
151 }
152
153 TrajectoryStateClosestToPoint PerigeeConversions::trajectoryStateClosestToPoint
154 (const AlgebraicVector3& momentum, const GlobalPoint& referencePoint,
155 const TrackCharge& charge, const AlgebraicSymMatrix66& theCovarianceMatrix,
156 const MagneticField* field) const
157 {
158 AlgebraicMatrix66 param2cart = jacobianParameters2Cartesian
159 (momentum, referencePoint, charge, field);
160 CartesianTrajectoryError cartesianTrajErr(ROOT::Math::Similarity(param2cart, theCovarianceMatrix));
161
162 FTS theFTS(GlobalTrajectoryParameters(referencePoint,
163 momentumFromPerigee(momentum, charge, referencePoint, field), charge,
164 field), cartesianTrajErr);
165
166 return TrajectoryStateClosestToPoint(theFTS, referencePoint);
167 }
168
169
170 AlgebraicMatrix66
171 PerigeeConversions::jacobianParameters2Cartesian(
172 const AlgebraicVector3& momentum, const GlobalPoint& position,
173 const TrackCharge& charge, const MagneticField* field) const
174 {
175 if (momentum[0]==0.) throw cms::Exception("PerigeeConversions", "Track with rho=0");
176 double factor = 1.;
177 double bField = field->inInverseGeV(position).z();
178 if (charge!=0 && fabs(bField)>1.e-10) {
179 // if (bField==0.) throw cms::Exception("PerigeeConversions", "Field is 0");
180 factor = -bField*charge;
181 }
182 AlgebraicMatrix66 frameTransJ;
183 frameTransJ(0,0) = 1;
184 frameTransJ(1,1) = 1;
185 frameTransJ(2,2) = 1;
186 frameTransJ(3,3) = - factor * cos(momentum[2]) / (momentum[0]*momentum[0]);
187 frameTransJ(4,3) = - factor * sin(momentum[2]) / (momentum[0]*momentum[0]);
188 frameTransJ(5,3) = - factor / tan(momentum[1]) / (momentum[0]*momentum[0]);
189
190 frameTransJ(3,5) = - factor * sin(momentum[2]) / (momentum[0]);
191 frameTransJ(4,5) = factor * cos(momentum[2]) / (momentum[0]);
192 frameTransJ(5,4) = - factor / (momentum[0]*sin(momentum[1])*sin(momentum[1]));
193
194 return frameTransJ;
195 }
196
197
198 AlgebraicMatrix55
199 PerigeeConversions::jacobianCurvilinear2Perigee(const FreeTrajectoryState& fts) const {
200
201 GlobalVector p = fts.momentum();
202
203 GlobalVector Z = GlobalVector(0.,0.,1.);
204 GlobalVector T = p.unit();
205 GlobalVector U = Z.cross(T).unit();;
206 GlobalVector V = T.cross(U);
207
208 GlobalVector I = GlobalVector(-p.x(), -p.y(), 0.); //opposite to track dir.
209 I = I.unit();
210 GlobalVector J(-I.y(), I.x(),0.); //counterclockwise rotation
211 GlobalVector K(Z);
212 GlobalPoint x = fts.position();
213 GlobalVector B = fts.parameters().magneticField().inInverseGeV(x);
214 GlobalVector H = B.unit();
215 GlobalVector HxT = H.cross(T);
216 GlobalVector N = HxT.unit();
217 double alpha = HxT.mag();
218 double qbp = fts.signedInverseMomentum();
219 double Q = -B.mag() * qbp;
220 double alphaQ = alpha * Q;
221
222 double lambda = 0.5 * M_PI - p.theta();
223 double coslambda = cos(lambda), tanlambda = tan(lambda);
224
225 double TI = T.dot(I);
226 double NU = N.dot(U);
227 double NV = N.dot(V);
228 double UI = U.dot(I);
229 double VI = V.dot(I);
230 double UJ = U.dot(J);
231 double VJ = V.dot(J);
232 double UK = U.dot(K);
233 double VK = V.dot(K);
234
235 AlgebraicMatrix55 jac;
236
237 if( fabs(fts.transverseCurvature())<1.e-10 ) {
238 jac(0,0) = 1/coslambda;
239 jac(0,1) = tanlambda/coslambda/fts.parameters().momentum().mag();
240 }else{
241 double Bz = B.z();
242 jac(0,0) = -Bz/coslambda;
243 jac(0,1) = -Bz * tanlambda/coslambda*qbp;
244 jac(1,3) = alphaQ * NV * UI/TI;
245 jac(1,4) = alphaQ * NV * VI/TI;
246 jac(0,3) = -jac(0,1) * jac(1,3);
247 jac(0,4) = -jac(0,1) * jac(1,4);
248 jac(2,3) = -alphaQ/coslambda * NU * UI/TI;
249 jac(2,4) = -alphaQ/coslambda * NU * VI/TI;
250 }
251 jac(1,1) = -1.;
252 jac(2,2) = 1.;
253 jac(3,3) = VK/TI;
254 jac(3,4) = -UK/TI;
255 jac(4,3) = -VJ/TI;
256 jac(4,4) = UJ/TI;
257
258 return jac;
259
260 }
261
262
263
264 AlgebraicMatrix55
265 PerigeeConversions::jacobianPerigee2Curvilinear(const GlobalTrajectoryParameters& gtp) const {
266
267 GlobalVector p = gtp.momentum();
268
269 GlobalVector Z = GlobalVector(0.f,0.f,1.f);
270 GlobalVector T = p.unit();
271 GlobalVector U = Z.cross(T).unit();;
272 GlobalVector V = T.cross(U);
273
274 GlobalVector I = GlobalVector(-p.x(), -p.y(), 0.f); //opposite to track dir.
275 I = I.unit();
276 GlobalVector J(-I.y(), I.x(),0.f); //counterclockwise rotation
277 GlobalVector K(Z);
278 GlobalPoint x = gtp.position();
279 GlobalVector B = gtp.magneticField().inInverseGeV(x);
280 GlobalVector H = B.unit();
281 GlobalVector HxT = H.cross(T);
282 GlobalVector N = HxT.unit();
283 double alpha = HxT.mag();
284 double qbp = gtp.signedInverseMomentum();
285 double Q = -B.mag() * qbp;
286 double alphaQ = alpha * Q;
287
288 double lambda = 0.5 * M_PI - p.theta();
289 double coslambda = cos(lambda), sinlambda = sin(lambda);
290 double mqbpt = -1./coslambda * qbp;
291
292 double TJ = T.dot(J);
293 double TK = T.dot(K);
294 double NU = N.dot(U);
295 double NV = N.dot(V);
296 double UJ = U.dot(J);
297 double VJ = V.dot(J);
298 double UK = U.dot(K);
299 double VK = V.dot(K);
300
301 AlgebraicMatrix55 jac;
302
303 if( fabs(gtp.transverseCurvature())<1.e-10f ) {
304 jac(0,0) = coslambda;
305 jac(0,1) = sinlambda/coslambda/gtp.momentum().mag();
306 }else{
307 jac(0,0) = -coslambda/B.z();
308 jac(0,1) = -sinlambda * mqbpt;
309 jac(1,3) = -alphaQ * NV * TJ;
310 jac(1,4) = -alphaQ * NV * TK;
311 jac(2,3) = -alphaQ/coslambda * NU * TJ;
312 jac(2,4) = -alphaQ/coslambda * NU * TK;
313 }
314 jac(1,1) = -1.;
315 jac(2,2) = 1.;
316 jac(3,3) = UJ;
317 jac(3,4) = UK;
318 jac(4,3) = VJ;
319 jac(4,4) = VK;
320
321 return jac;
322 }
323
324 // AlgebraicMatrix
325 // PerigeeConversions::jacobianHelix2Perigee(const reco::helix::Parameters & helixPar,
326 // const reco::helix::Covariance & helixCov) const
327 // {
328 // AlgebraicMatrix55 jac;
329 //
330 // jac(3,0) = 1.;
331 // jac(2,1) = 1.;
332 // // jac(0,2) = - 1. / magField.inTesla(helixPar.vertex()).z() * 2.99792458e-3;
333 // jac(0,2) = - 1. / (TrackingTools::FakeField::Field::inTesla(helixPar.vertex()).z() * 2.99792458e-3);
334 // jac(4,3) = 1.;
335 // jac(1,4) = -(1. + helixPar.tanDip()*helixPar.tanDip());
336 // std::std::cout << jac;
337 // return jac;
338 // }